Membership Service in ASP.Net 2.0

Membership Service in ASP.Net 2.0
Published on http://asp.net on 10/16/2008

Tuesday, August 13, 2013

SQL Cache Invalidation

1      Introduction



Caching has been one of the most efficient features in ASP.NET to dramatically improve the performance of a web application. Caching can be defined as storing the frequently used items in memory. This document provides bottlenecks of Caching in data driven web applications, introduces a new feature “SQL Cache Invalidation” in ASP.Net 2.0, and how it can be implemented to overcome the current drawbacks in ASP.Net 1.x.


2      Caching in ASP.NET 1.x

In the existing ASP.NET 1.x framework, the one and only drawback to caching is the problem of stale data. If you cache the contents of a database table in memory, and the records in the underlying database table change, then your Web application will display old, inaccurate data. For certain types of data you might not care if the data being displayed is slightly out of date, but for other types of data—such as stock prices and auction bids—displaying data that is even slightly stale is unacceptable.

The initial release of the Microsoft ASP.NET framework did not provide a good solution to this problem. When using the ASP.NET 1.x framework, you just had to live with this tradeoff between performance and stale data. Fortunately, the Microsoft ASP.NET 2.0 framework includes a new feature called SQL Cache Invalidation that solves this problem.


3      SQL Cache Invalidation

SQL Cache Invalidation is one of the most anticipated new features of the ASP.NET 2.0 framework. By taking advantage of SQL Cache Invalidation, you get all of the performance benefits of caching without the problem of stale data. SQL Cache Invalidation enables you to automatically update data in the cache whenever the data changes in the underlying database.

SQL Cache Invalidation works only with SQL Server database with version 7.0 and higher. Behind the scenes, SQL Cache Invalidation works differently in SQL Server 7.0/2000 and SQL Server 2005 code named Yukon.

3.1    SQL Cache Invalidation in SQL Server 2005

Whenever changes occur in a database table, Yukon proactively notifies ASP.NET via IIS that the related cache must be invalidated. The plumbing to support caching is built into ASP.NET and SQL Server 2005, so implementation is greatly simplified compared to SQL 7/2000.






3.2    SQL Cache Invalidation in SQL Server 7.0/2000

Cache Invalidation in SQL Server 7.0 and SQL Server 2000 are handled in the same manner.  Rather than being proactively notified, such as caching dependency in Yukon, ASP.NET must monitor the database table that you have a caching dependency on.  There is no notification model built into SQL Server 7.0 or SQL Server 2000.

.NET Framework 2.0 ships with utilities that automatically prepare a database table for dependency caching.  After running these utilities, additional cache tables are created in your database.  Additionally, triggers are added to your tables to populate the new tables.  Whenever a change occurs in your table, the cache tables are altered.  A process within ASP.NET periodically monitors the cache table and determines whether or not a change has occurred.  If a change has occurred, this process invalidates the respective cache items.

The following figure describes at a high level the caching in SQL Server 7.0/2000.






It is important to understand that SQL Cache Invalidation only works with Microsoft SQL Server version 7 and higher. You cannot use this feature with other databases such as Microsoft Access or Oracle.

You can use SQL Cache Invalidation when caching the output of an entire page, when working with the DataSource controls, or when working directly with the Cache object. We'll examine all three scenarios.


4      Configuring SQL Cache Invalidation

Before you can take advantage of SQL Cache Invalidation in your Web application, you must first perform some configuration steps. You must configure Microsoft SQL Server to support SQL Cache Invalidation and you must add the necessary configuration information to your application's Web configuration file.

4.1    Configuring SQL Server

There are two ways that you can configure SQL Server. You can either use the aspnet_regsql command line tool, or you can take advantage of the SqlCacheDependencyAdmin class.

 4.1.1 Enabling SQL Cache Invalidation with ASPNET_REGSQL

The aspnet_regsql tool enables you to configure SQL Cache Invalidation from the command line. The aspnet_regsql tool is located in your Windows\Microsoft.NET\Framework\[version] folder. You must use this tool by opening a command prompt and navigating to this folder.
In order to support SQL Cache Invalidation when using the Pubs database, you need to execute the following command.

aspnet_regsql -E -d Pubs -ed 

The -E option causes the aspnet_regsql tool to use integrated security when connecting to your database server. The -d option selects the Pubs database. Finally, the -ed option enables the database for SQL Cache Invalidation.
When you execute this command, a new database table named AspNet_SqlCacheTablesForChangeNotification is added to the database. This table contains a list of all of the database tables that are enabled for SQL Cache Invalidation. The command also adds a set of stored procedures to the database.
After you enable a database for SQL Cache Invalidation, you must select the particular tables in the database that you will enable for SQL Cache Invalidation. The following command enables the Titles database table.

aspnet_regsql -E -d Pubs -t Titles -et 

The -t option selects a
database table. The -et option enables a database table for SQL Cache
Invalidation. You can, of course, enable multiple tables by re-executing this
command for each database table.
When you execute this command, a trigger is added to the database table. The trigger fires whenever you make a modification to the table and it updates the AspNet_SqlCacheTablesForChangeNotification table.
Finally, if you want to get the list of tables that are currently enabled for SQL Cache Invalidation in a particular database, you can use the following command.


aspnet_regsql -E -d Pubs -lt 
This command selects the list of tables from the AspNet_SqlCacheTablesForChangeNotification. Alternatively, you could retrieve this information by performing a query directly against this database table.

 

4.1.2 Using the SqlCacheDependencyAdmin Class

Behind the scenes, the aspnet_regsql tool uses the methods of the SqlCacheDependencyAdmin class to configure Microsoft SQL Server. If you prefer, you can use the methods of this class directly from within an ASP.NET page.

The SqlCacheDependencyAdmin class has five important methods:

·         DisableNotifications—Disables SQL Cache Invalidation for a particular database.
·         DisableTableForNotifications—Disables SQL Cache Invalidation for a particular table in a database.
·         EnableNotifications—Enables SQL Cache Invalidation for a particular database.
·         EnableTableForNotifications—Enables SQL Cache Invalidation for a particular table in a database.
·         GetTablesEnabledForNotifications—Returns a list of all tables enabled for SQL Cache Invalidation.
 
For example, the ASP.NET page in Listing 2 enables you to configure SQL Cache Invalidation for any table in the Pubs database (see Figure 2).


Figure 2. Enabling SQL Cache Invalidation from an ASP.NET page

Listing 2. EnableSCI.aspx (C#)

<%@ Page Language="c#" %>
<%@ Import Namespace="System.Web.Caching" %>
<script runat="server">
 
    const string connectionString = "Server=localhost;Database=Pubs";
 
    void Page_Load()
    {
        if (!IsPostBack)
        {
            SqlCacheDependencyAdmin.EnableNotifications(
            connectionString);
            SqlDataSource1.SelectParameters.Add("connectionString", 
            connectionString);
        }
    }
 
    void EnableTable(Object s, EventArgs e)
    {
        try
        {
            SqlCacheDependencyAdmin.EnableTableForNotifications(
              connectionString, txtTableName.Text);
        }
        catch (Exception ex)
        {
            lblErrorMessage.Text = ex.Message;
        }
        txtTableName.Text = "";
    }
 
</script>
 
<html>
<head runat="server">
    <title>Enable SQL Cache Invalidation</title>
</head>
<body>
    <form id="form1" runat="server">
    
    <h1>SQL Cache Invalidation</h1>
    
    The following tables are enabled for SQL Cache Invalidation:
 
    <p>
    <asp:GridView id="grdTables" 
      DataSourceID="SqlDataSource1" CellPadding="10" 
      ShowHeader="false" Runat="Server" />
    </p>
    
    <asp:ObjectDataSource 
        ID="SqlDataSource1" 
        TypeName="System.Web.Caching.SqlCacheDependencyAdmin"
        SelectMethod="GetTablesEnabledForNotifications"
        Runat="Server" />
    <p>
    <asp:Label ID="lblErrorMessage" EnableViewState="false" 
      ForeColor="red" Runat="Server" />
    </p>
 
     <asp:TextBox ID="txtTableName" Runat="Server" /> 
     <asp:Button Text="Enable Table" OnClick="EnableTable" 
       Runat="Server" /> 
 
    </form>
</body>
</html> 


In Listing 2, the connectionString constant is used to select the database for which SQL Cache Invalidation is enabled (You can change the value of this constant when you want to enable SQL Cache Invalidation for a database other than the Pubs database). Within the Page_Load method, the EnableNotifications method on the SqlCacheDependencyAdmin class is called to enable SQL Cache Invalidation for the database specified by the connectionString constant.

The GridView in Listing 2 displays all of the database tables that are currently enabled for SQL Cache Invalidation. The GridView is bound to an ObjectDataSource control that calls the GetTablesneabledForNotifications method for its SelectMethod.

Finally, you can use the page in Listing 2 to enable additional tables for SQL Cache Invalidation. When you enter the name of a table in the textbox and click the Enable Table button, the EnableTableForNotifications method is called.

4.2  Web Configuration Settings for SQL Cache Invalidation

The next step, before you can use SQL Cache Invalidation in your ASP.NET application, is to update your Web configuration file. You need to configure the ASP.NET framework to poll the databases that you have enabled for SQL Cache Invalidation.
The Web configuration file in Listing 3 contains the necessary configuration information to poll the Pubs database.
Listing 3. Web.Config

<configuration>
      
  <connectionStrings>
    <add name="mySqlServer" 
      connectionString="Server=localhost;Database=Pubs" />
  </connectionStrings>
        
  <system.web>
 
    <caching>
      <sqlCacheDependency enabled="true">
      <databases>
      <add
            name="Pubs"
            connectionStringName="mySqlServer"
            pollTime="60000" />
      </databases>
</sqlCacheDependency>
    </caching>
    </system.web>
</configuration> 


The Web configuration file in Listing 3 contains two sections. The <connectionStrings> section is used to create a database connection string to the Pubs database named mySqlServer.
The caching section is used to configure the SQL Cache Invalidation polling. Within the <databases> subsection, you can list one or more databases that you want to poll for changes. In Listing 3, the database represented by the mySqlServer is polled once a minute (every 60000 milliseconds).
You can specify different polling intervals for different databases. The server must do a little bit of work every time the database is polled for changes. If you don't expect the data in the database to change very often, then you can increase the polling interval.

5      Using SQL Cache Invalidation

You can use SQL Cache Invalidation in three scenarios: when caching the output of an entire page, when working with the DataSource controls, or when working directly with the Cache object. We'll examine these three scenarios.

1.1    Using SQL Cache Invalidation with Page Output Caching

Now that we've gotten all of the configuration steps for SQL Cache Invalidation out of the way, we can start taking advantage of it in our ASP.NET pages. One way that you can use SQL Cache Invalidation is with page output caching. Page output caching enables you to cache the entire rendered contents of a page in memory. By taking advantage of SQL Cache Invalidation, you can automatically update the cached page when, and only when, a change is made to a database table.
For example, the page in Listing 4 displays the contents of the Titles database table in a GridView control. At the top of the page, the OutputCache directive is used to cache the contents of the page in memory. The SqlDependency attribute causes the page to be updated whenever the Titles database table changes.

Listing 4. OutputCacheTitles.aspx
<%@ OutputCache SqlDependency="Pubs:Titles" 
    Duration="6000" VaryByParam="none" %>
<html>
<head runat="server">
    <title>Output Cache Titles</title>
</head>
<body>
    <form id="form1" runat="server">
    
    <%= DateTime.Now %>
 
    <asp:GridView 
      ID="grdTitles" 
      DataSourceID="SqlDataSource1" 
      Runat="Server" />    
    
    <asp:SqlDataSource
      ID="SqlDataSource1"
      SelectCommand="Select * FROM Titles"
      ConnectionString="<%$ ConnectionStrings:mySqlServer %>"
      Runat="Server" />
    
    </form>
</body>
</html> 

Notice that the SqlDependency attribute references the name of the database defined within the Web configuration file. Since we specified that the Pubs database should be polled once every minute for changes, if a change is made to the database the page in Listing 4 will be updated within a minute.

You can list more than one database and/or more than one database table for the value of the SqlDependency attribute. To create more than one dependency, simply separate each dependency with a semicolon.

5.2    Using SQL Cache Invalidation with the DataSource Control

As an alternative to using SQL Cache Invalidation with page output caching, you can use SQL Cache Invalidation directly with the DataSource controls. You should consider using SQL Cache Invalidation with the DataSource controls when you need to work with the same database data in multiple pages. The SqlDataSource, AccessDataSource, and ObjectDataSource controls all support a SqlCacheDependency property.

For example, the page in Listing 5 uses the SQL Cache Invalidation with the SqlDataSource control.

Listing 5. SqlDataSourceCaching.aspx
<html>
<head id="Head1" runat="server">
    <title>SqlDataSource Caching</title>
</head>
<body>
    <form id="form1" runat="server">
 
        <%= DateTime.Now %>
 
        <asp:GridView 
            ID="grdTitles" 
            DataSourceId="SqlDataSource1"
            Runat="server" />
            
        <asp:SqlDataSource 
            ID="SqlDataSource1" 
            EnableCaching="true"
            SqlCacheDependency="Pubs:Titles"
            SelectCommand="select * from titles"
            ConnectionString="<%$ ConnectionStrings:mySqlServer %>"
            Runat="server" />
   
    </form>
</body>
</html> 

In Listing 5, the SqlDataSource control is declared with both an EnableCaching attribute and a SqlCacheDependency attribute. The SqlCacheDependency property uses the same syntax as the OutputCache directive's SqlDependency attribute. You list the name of the database, followed by the name of the database table.

5.3    Using SQL Cache Invalidation with the Cache Object

A final option is to use SQL Cache Invalidation with the Cache object. This option provides you with the greatest degree of programmatic control over SQL Cache Invalidation.
To use SQL Cache Invalidation with the Cache object, you need to create an instance of the SqlCacheDependency object. You can use the SqlCacheDependency object when inserting a new object into the Cache with the Insert method.
For example, the page in Listing 6 displays the number of records in the Titles database table. The count is cached with a dependency on the underlying database table.
Listing 6. DisplayTitleCount.aspx (C#)
<%@ Page Language="c#" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server">
 
    void Page_Load() 
    {
        int count = 0;
 
        if (Cache["TitleCount"] != null)
        {
            count = (int)Cache["TitleCount"];
        }
        else
        {
            string connectionString = 
              ConfigurationSettings.ConnectionStrings[
              "mySqlServer"].ConnectionString;
            SqlConnection con = new SqlConnection(connectionString);
            SqlCommand cmd = new 
              SqlCommand("SELECT Count(*) FROM Titles", con);
            con.Open();
            count = (int)cmd.ExecuteScalar();
            con.Close();
            Cache.Insert("TitleCount", count, 
              new SqlCacheDependency("Pubs", "Titles"));
        }
        lblTitleCount.Text = count.ToString();
    }
 
</script>
<html>
<head runat="server">
    <title>Display Title Count</title>
</head>
<body>
    <form id="form1" runat="server">
 
    <asp:Label ID="lblTitleCount" Runat="Server" />    
    
    </form>
</body>

</html>

6      Conclusion

Caching has a dramatic impact on the performance of database-driven Web applications. Fortunately, the ASP.NET 2.0 framework includes a number of significant new enhancements that make it easier to take advantage of caching in your applications.

The new support for SQL Cache Invalidation enables you to automatically reload database data in the cache whenever the data is modified in the underlying database. This feature provides you with all the performance benefits of caching, without the worries of stale data.

Tuesday, April 16, 2013

Handling overflow exceptions: Checked/Unchecked


In .Net, when two numbers are added, the corresponding IL code that is generated has two representation and by default .add call is executed.

1. add
2. add.ovf

Because .add is called, the overflows go undetected and might cause the applications built around it to behave erratically. In Order to ensure the overflow check, use of "checked" keyword could be employed

e.g.

Without "checked"


                byte b1 = 100;
                byte b2 = (byte)(b1 + 200);
                Console.WriteLine(b2.ToString());
                Console.ReadKey();

on executing the above piece of the code output would be : 44
Since byte can be b/w 0 and 255. 300-256 =44


       
With "checked"



               byte b1 = 100;
                byte b2 = checked((byte)(b1 + 200));
                Console.WriteLine(b2.ToString());
                Console.ReadKey();

in this case, overflow exception will be thrown.

Similarly, the "unchecked" keyword can be used to perform the reciprocal of "checked" operation.

Likewise as explained above, the OPCodes for Subtract, Multiply, Divide also exist.

Monday, April 15, 2013

"is" vs "as" keywords in .Net

Coming soon....

String vs string

Developers at time use "String" and sometimes "string" and often get posed with the question as to which is correct.

Answer : Either of it could be used as base type for string is System.String (CTS Data Type), string is specific to C#

== vs .Equals()

In .Net you could use "==" or .Equals()

== will return true if the reference types are pointing to object in Memory.

.Equals will perform case sensitive and character by character equality check.


            StringBuilder a = new StringBuilder("anubhav");
            StringBuilder b = new StringBuilder("anubhav");

            if (a == b)
                Console.WriteLine("a==b is true");
            else
                Console.WriteLine("a==b is false");

            if(a.Equals(b))
                Console.WriteLine("a.equals(b) is true");
            else
                Console.WriteLine("a.equals(b) is false");


Output :
a==b is false
a.equals(b) is true

Wednesday, October 26, 2005

VC++.Net - Editor incorrectly formats CONTROL statements

Issue

This was not a problem under Visual Studio 6. But in VS 2003.Net it persists.

It appears that in some situations the editor incorrectly formats CONTROL statements. This only seems to happen when the control has a Help ID, but it does not always happen even then.

An example:

CONTROL "",IDC_CFG_LISTER_ITEM_COLOUR_FG,"dopus.dropdown.button", 0x5,137,16,30,13,0,0,HIDC_CFG_LISTER_ITEM_COLOUR_FG

In this example, there is one too many parameters. The ",0,0" preceding the HIDC_xxx should only be ",0", eg:

CONTROL "",IDC_CFG_LISTER_ITEM_COLOUR_FG,"dopus.dropdown.button", 0x5,137,16,30,13,0,HIDC_CFG_LISTER_ITEM_COLOUR_FG

When this resource script is complied it produces the following errors:

Compiling resources....\language.rc(290) : error RC2111 : invalid control type.\language.rc(290) : error RC2113 : END expected in dialog.\language.rc(291) : error RC2135 : file not found:.\language.rc(292) : error RC2135 : file not found:.\language.rc(294) : error RC2108 : expected numerical dialog constant

Removing the erroneous ",0" fixes the problem, however the next time any dialog in the resource file is edited, the ",0"s are all put back in.


Workaround

Workaround would be to set the HELP ID property dynamically at runtime.

You can follow the below steps to achieve this:

Let us assume we want to add help id to a TAB control having ID IDC_TAB1.
Open resource.hm file and add the #define as given below to specify value for HELP ID

#define HIDC_TAB1 1000 // some unique value for each control

If resource.hm file does not exist add a new file by name “resource.hm” in the Headers folder of the project. Also add, #include reaource.hm file in dialog editor’s header file.

Go to ::OnInitDialog() function of the Dialog and add the following code.

BOOL CSRTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();

----
----

CWnd* pwnd = this->GetDlgItem(IDC_TAB1);
pwnd->SetWindowContextHelpId(HIDC_TAB1);

return TRUE; // return TRUE unless you set the focus to a control
}

The same is depicted in the figure below:-



However, you would be happy to know, that the issue is fixed in VS2005.Net.
Using VS2003.Net, we created a MFC application (dialog box editor) and added a Tab control on to the editor. Build fails and enumerates the compilation errors as posted by you.

Then the same was emulated using VS2005.Net and the solution build perfectly without any compilation errors. Opening the .rc file complied with VS2005.Net in notepad, you will find that the code generated is what is below:-

CONTROL "",IDC_TAB1,"SysTabControl32",0x0,53,33,50,30,0,HIDC_TAB1

In VS2003.Net, the same procedure resulted in

CONTROL "",IDC_TAB1,"SysTabControl32",0x0,53,33,50,30,0,0,HIDC_TAB1

Part I - Deployment of Office-based Applications(VSTO)

Issue

Create a simple VSTO project, deploy to localhost. If you transfer these files to a computer that has never had Visual Studio 2005 installed, open the workbook, delete Sheet1, then save the workbook under a new name, opening the workbook results in an error that the customization assembly cannot be found.

Resolution

One possible workaround that the you may be able to employ is to rename Sheet1 so that it has a unique name that is not likely to be reproduced and then set the XLSheetVisibility property of this sheet using VBA code so that it is set to xlSheetVeryHidden.By hiding the worksheet in this fashion it would make it more difficult for the client to delete this worksheet from the workbook. The problem as originally understood from the repro steps was that if the user deleted Sheet1 from the Excel workbook that was part of a VSTO solution that once they saved, closed and then reopened the workbook they received the error that the "Customization assembly could not be found or could not be loaded". Based on the description of the problem and as a result of tests if the user was to delete Sheet2 or Sheet3, given the workbook that was provided, then the problem does not occur and the VSTO code successfully loads.So by renaming and hiding Sheet1 from the user it would be less likely that they would delete this sheet and thereby prevent the scenario which results in the error while still allowing the VSTO code to execute. An assumption is made that there is no code contained within the Sheet1 class and/or no .NET controls residing on Sheet1.

It is often recommended that users do not delete sheets from a workbook that is part of a VSTO 2005 solution.

Another way you could do it is to follow the following

There may be another option which would prevent the error from occurring.

If the "Trust access to Visual Basic Project" option is enabled within Microsoft Excel then if the user deletes Sheet1 and there is no code behind or controls on this sheet they should be able to save, close and then reopen the workbook without receiving the error and the VSTO code should still execute.I would also indicate that changing this setting could pose a potential security hazard.By enabling this setting you are allowing macros or automation code to have access to the core Visual Basic objects, methods, and properties which could potentially allow malicious code to be inserted into a workbook and then be executed when the workbook is opened.

For more information please see the url below.http://office.microsoft.com/en-us/assistance/HA011403191033.aspx

Tuesday, September 27, 2005

Deploying ASP.Net 2.0 Beta 2 applications

Issue

You build a simple web application using .NET and SQL Express beta 2. Add a setup project to the solution. If the target machine has the .NET framework beta 2, setup runs fine. If not, the user is presented with the .NET framework license agreement, and it begins to automatically download 3 files. On the 2nd file, it terminates with a message indicating that WindowsInstaller-KB884016-v2-x86.exe has changed since it was initially published.

Resolution

1. When you add a web setup project to website solution created using VS 2005 Beta 2à right click on the WebSetup1 and WebSetup1 Property Pages would open up.

2. Click on the “Settings” button and the Pre-requisites page would open up. Uncheck the “Create setup Project” at the top as you can see in the screen. Click Ok.

3. Build the website. Then, add the Project Output Group to the WebSetup1.

4. Build the WebSetup1 Project. Open the website folder where the solution is i.e. “\\My Documents\Visual Studio 2005\Projects\YourWebSite\WebSetup1\Debug” and you will have only the .msi file.

5. Download the bootstrapper_sample.exe from Microsoft site.

http://www.microsoft.com/downloads/details.aspx?FamilyId=BF253CFD-1EFC-4FC5-BA7E-6A6F21403495&displaylang=en

This is a self-extracting executable, and will produce two files when run: Setup.exe and Setup.ini. Place these in the same directory as your MSI file.

6. You will also need to obtain the .NET Framework Redistributable Package (Dotnetfx.exe). In your case, this would be NET Framework Version 2.0 Redistributable Package Beta 2 (x86)
http://www.microsoft.com/downloads/details.aspx?FamilyId=7ABD8C8F-287E-4C7E-9A4A-A4ECFF40FC8E&displaylang=en

7. Place Dotnetfx.exe in the same directory as your MSI and the Bootstrapper sample files. These four files (Setup.exe, Setup.ini, Dotnetfx.exe, and your MSI file) constitute your new installation package

8. Before copying these files to the target machine, you need to make some changes to Setup.ini. Open Setup.ini in a notepad, and change the following lines.


Msi=FxCopSourceSetup.msi should be changed to Msi=NameofMSIFile.msi (your MSI).
'FxInstallerPath=c: should be uncommented. For instance, FxInstallerPath=. in case the Dotnetfx.exe is in the same directory as setup.exe. Finally it would look something like below:-


Then copy these onto target machine and run Setup.exe and it will install .Net FRamework 2.0 Beta 2 and webiste can be deployed successfully.

Enjoy!!!!!!!!!!!!!!

Thursday, August 18, 2005

Site Navigation in ASP.Net 2.0 - Part I

Site Navigation

All of the web applications developed usually have more than one page and they are usually interconnected via some mechanism. In ASP.Net 1.x, navigation was made possible by using hyperlinks with the help of include file or user controls. They are pretty handy but not so much when the pages are moved around or their names change.

So in order to overcome this drawback, ASP.Net 2.0 introduces the new Site Navigation System. Site navigation uses the layered architecture. Controls such as Menu and TreeView provide the navigation UIs. Classes such as SiteMap and SiteMapNode provide the API that the controls rely on and also constitute an API you can use yourself if you wish. Site navigation is provider-based, and the one site map provider that comes with ASP.NET 2.0 -->XmlSiteMapProvider --> reads site maps from XML data files. By default, those files are named Web.sitemap.

Lets us discuss each on of them one at a time.

Site Maps

Site Maps help us define the layout of all the pages in the application and their inherent relation with each other. For this, one could either use the SiteMap Class or the SiteMapDataSource control.
SiteMapDataSource controls use site map providers to read site maps. They then provide the site map data to the controls they're bound to. Binding a TreeView to a SiteMapDataSource transforms each node in the site map into a TreeView node; binding a Menu to a SiteMapDataSource transforms each node in the site map into a menu item. The only site map provider that comes with ASP.NET 2.0 is XmlSiteMapProvider. It enables site maps to be read from XML files that conform to a predefined schema

Take up the following steps to create a site map-->

  • Start Visual Studio 2005 IDE.
  • Create a new ASP.Net website using C# as language on file system.
  • Right Click on solution and add a new item. From the Add item Wizard, add a new site map. Let the name be Web.sitemap (default name)
  • Add the following code to it:-

Only one sitemap element can be there in the site map file and there can be multiple siteMapNode element within the root node i.e. sitemap

Within the siteMapNode element, we have following attributes -->

  • Title --> This is actual description which appears as a hyperlink.
  • Description --> Tool Tip which comes up when we hover over that particular siteMapNode.
  • url --> this is the file located within the solution. It can be located within the root folder or within a sub-folder created within the solution.
  • Role --> the roles to which the links should be accessible.

    "Security trimming" refers to SiteMapDataSource's ability to hide nodes from users who lack proper authorization. Authorization is role-based and is enacted by including roles attributes in siteMapNode elements. Of course, you can use ASP.NET 2.0 Role Management service to define roles and map users to roles. Security trimming is disabled by default in XmlSiteMapProvider. You can enable it by including these statements in Web.config.

SiteMapPath Control

This control creates a navigation hierarchy what is sometimes referred to as Bread crumb navigation. The SiteMapPath control does not need a data source. All one needs is to drag and drop a SiteMap path control onto the page and you all have the results at your disposal. You can change the properties such as the depth of the hierarchy and styles.

Wednesday, August 17, 2005


Role Management in ASP.Net 2.0


As stated before, role management service deals with the authorization i.e. granting access and managing roles of each of the user registered with the web site.

Unlike Membership service which can either use the login server controls to achieve the task, role management service does not offer any server controls. All you have are a set of role management APIs within the system.web.security namespace.

Since ASP.Net 2.0 has a provider based model, role management also uses a set of providers for authorization. By default Beta 2 provides support for SQL Express only. For the remaining data stores you have to explicitly create a provider. I’ll be explaining every thing with respect to the SQL Provider that we created earlier for membership provider. To achieve the same, we will be going back to web.config file of our website solution that we created earlier.

Add the following section to the web.config file:-



Unlike membership service, role manager needs to enabled explicitly for it to work as specified by enabled="true".
Change the value against the type attribute with what you have in machine.config file as explained before.Also, note the connection string name is same as what we created earlier. For conveniece I am re-writing the same.



aspnetdb is the database which contains table for role managements as well.

Let’s assume you have folder Admin which has certain pages that should be accessible to only to the user with administrator rights. For this follow the following steps -->

  1. Create a new web.config file within the Admin folder by right clicking on the folder name and click “Add new Item”. Select the web.config file and click Add.
  2. Once done, add authorization section so that web.config file within the Admin folder looks something like as stated below -->

3.Now run the ASP.Net website configuration tool once again by navigating to Website--> ASP.Net configuration from the IDE menu. Once the ASP.Net configuration page opens up in the browser click on the provider tab and select link which states “select a different provider for each feature (Advanced)”.


Though I have demonstrated this to you earlier, below screenshot shows the new role provider is added to existing list of providers.

Now your web.config file is all set to use role management service.
Create another web “Manage.aspx” within the admin folder of the website solution. It looks something shown below:-

The source code for the same is:-

The above code is interface that the user will be presented with when he tries to create a new role or delete role if no user assigned to that role. It also delete role if any user is assigned to it. Please note that when a role is deleted with the users in it, those users would not be deleted from other roles.

When the page is run, it presents the user with the set of existing roles in the listbox.
For that you need to add a page load event with the following code:-

Roles in a membership API which has a number of method implemented within it. We will describe them briefly as and when required. If you notice in the code above we have
Roles.GetAllRoles () methodà is used to fetch all the roles from the aspnet_Roles table within the aspnetdb database.

Once all the roles are returned, it is possible that admin would want to add a new role.
Role management’s Role API has a new method CreateRole which takes a single string parameter --> Roles.CreateRole(txtBoxRole.Text);

It is likely that admin might try to add a role that already exists within the aspnet_Roles table and therefore this needs to be checked for before role is added to avoid redundant entries. For that we need to use RoleExists () method implemented within the role class. Roles.RoleExists (txtBoxRole.Text) is the method which checks to see if the role already exists in the table. It return a boolean value i.e. true or false.

This is what we are doing is piece of code below. On the button click of create role, it check to see if the role already exists. If it exists, a message is returned back to user prompting the same. In case it does not exist, it creates a new role using the CreateRole () method.

For that Add the following code to Create Role button:-

For deleting roles we have Role API offers following methods:-
-->
Roles.DeleteRole (String strRole);

This method would delete the role from the aspnet_Roles table in case there are not users assigned to this role. In case users are assigned to this role, then your job would be to remove the users from role and then delete the role. Note that there is difference when we remove users from a role in the fact that the users will be removed only from that specified role and not from the remaining roles. Add the following piece of code to remove role button click event:-

If you noticed, we have used another method --> Roles.GetUsersInRole(string strRole). This method is used to check if the users are contained in that role. If the length of the string is returned is 0, then we can delete the role using Roles.DeleteRole (strRole) method.

In case the length of the string returned is not zero, then we need to remove the users from that role and then delete the role.

Removing users from roles can use any one of the following construct -->

Roles.RemoveUserFromRole (string uname, string rolename)

Roles.RemoveUserFromRoles (string uname, string rolenames ())

Roles.RemoveUsersFromRole (string unames (), string rolename)

Roles.RemoveUsersFromRoles (string unames (), string rolenames ())

In our code, we want to remove users from that role and then delete the role. Therefore, we would be using the third construct -->

Roles.RemoveUsersFromRole(Roles.GetUsersInRole(strRole), strRole);

You can add the logic to the button “ remove role with users” and embed the construct appropriately wherever applicable. And then delete the role using the Roles.DeleteRole (strRole); method.

Managing Roles

Next we are going to discuss how to manage users and roles. That is, how to assign user to role and how to remove the user from role.

The source code for this page is :-

On this page, we have a drop down box which is binded to the SQL data source which in return uses a select query to fetch all the users from aspnet_Users table within the aspnetdb database. In the page_load event we bind the list box with all the Available roles. The code for the same is below :-

Below method gets called as soon after the page is loaded but before the controls are rendered on the page. It fetches all the roles for the first user in the drop down list.

Now, when Admin selects any of the users from the drop down box, we would want to see the roles that are already assigned to him/her. For this we add SelectedIndexChanged event on the drop down list as stated under:-

Before we go any further, look at the various constructs for adding the users:-

Roles.AddUserToRole (string uname, string rolename) --> Add user to a role
Roles.AddUsersToRole (string unames (), string rolename) --> Add multiple users to a role
Roles.AddUserToRoles (string uname, string rolenames ()) -- > Add a user to multiple roles
Roles.AddUsersToRoles (string unames (), string rolenames ()) --> Add multiple users to multiple roles

To add a user to particular role, add the following code to the Add role button click event.
This code checks to see if the user already exists in that particular role which is selected in the second list box against Add Role button. If the role is already assigned to a user, then it prompts for the same. Else the role would be assigned to user using the first construct described above.

Similarly, if you want to remove user from one or more roles you can go ahead using any of the below constructs:-

Roles.RemoveUserFromRole (string uname, string rolename)

Roles.RemoveUserFromRoles (string uname, string rolenames ())

Roles.RemoveUsersFromRole (string unames (), string rolename)

Roles.RemoveUsersFromRoles (string unames (), string rolenames ())


In the code below, we are doing through the items in the list box and removing the user from a particular role. Add the following code to the delete role button click event.

This is all I had to dicuss to in this article. You can drill into the details more by getting a good hold of these basics and moving on to advanced concepts.