Evjen c13.tex V2 - 01/28/2008 2:36pm Page 657 Chapter 13: Extending the Provider Model < roleManager defaultProvider="LimitedProvider" enabled="true" > < providers > < add connectionStringName="LocalSqlServer" applicationName="/" name="LimitedProvider" type="LimitedSqlRoleProvider" / > < /providers > < /roleManager > < /system.web > < /configuration > Remember that you have to define the provider to use in your application by providing a value for the defaultProvider attribute and defining that provider further in the < provider > section. You also have to enable the provider by setting the enabled attribute to true . By default, the role management system is disabled. Using the < add > element, you can add a provider instance that makes use of the LimitedSqlRole- Provider class. Because this provider derives from the SqlRoleProvider class, you must use some of the same attributes that this provider requires, such as the connectionStringName attribute that points to the connection string to use to connect to the specified SQL instance. After you have the new LimitedSqlRoleProvider instance in place and defined in the web.config file, you can use the Roles class in your application just as you normally would, but notice the behavior of this class is rather different from the normal SqlRoleProvider . To see it in action, construct a simple ASP.NET page that includes a TextBox, Button, and Label server control. The page should appear as shown in Listing 13-23. Listing 13-23: Using Roles.CreateRole() VB < %@ Page Language="VB" % > < script runat="server" > Protected Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Try Roles.CreateRole(TextBox1.Text) Label1.Text = "Role successfully created." Catch ex As Exception Label1.Text = ex.Message.ToString() End Try End Sub < /script > < html xmlns="http://www.w3.org/1999/xhtml" > < head runat="server" > < title > Main Page < /title > < /head > < body > < form id="form1" runat="server" > < div > Continued 657 Evjen c13.tex V2 - 01/28/2008 2:36pm Page 658 Chapter 13: Extending the Provider Model Role Name: < br / > < asp:TextBox ID="TextBox1" runat="server" >< /asp:TextBox >< br / > < br / > < asp:Button ID="Button1" runat="server" Text="Create Role" OnClick="Button1_Click" / >< br / > < br / > < asp:Label ID="Label1" runat="server" >< /asp:Label >< /div > < /form > < /body > < /html > C# < %@ Page Language="C#" % > < script runat="server" > protected void Button1_Click(object sender, EventArgs e) { try { Roles.CreateRole(TextBox1.Text); Label1.Text = "Role successfully created."; } catch (Exception ex) { Label1.Text = ex.Message.ToString(); } } < /script > This simple ASP.NET page enables you to type in a string value in the text box and to attempt to create a new role using this value. Note that anything other than the role Administrator and Manager results in an error. So, when the Roles.CreateRole() is called, an error is produced if the rules defined by the provider are not followed. In fact, running this page and typing in a role other than the Administrator or Manager role gives you the results presented in Figure 13-7. Figure 13-7 658 Evjen c13.tex V2 - 01/28/2008 2:36pm Page 659 Chapter 13: Extending the Provider Model To show this provider in action, create another ASP.NET page that allows you to add users to a particular role. As stated, this can be done with a number of available methods, but in this case, this example uses the Roles.AddUserToRole() method. This is illustrated in Listing 13-24. Listing 13-24: Attempting to add users to a role through the new role provider VB < %@ Page Language="VB" % > < script runat="server" > Protected Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Try Roles.AddUserToRole(TextBox1.Text, TextBox2.Text) Label1.Text = "User successfully added to role" Catch ex As Exception Label1.Text = ex.Message.ToString() End Try End Sub < /script > < html xmlns="http://www.w3.org/1999/xhtml" > < head runat="server" > < title > Main Page < /title > < /head > < body > < form id="form1" runat="server" > < div > Add the following user: < br / > < asp:TextBox ID="TextBox1" runat="server" >< /asp:TextBox >< br / > < br / > To role: < br / > < asp:TextBox ID="TextBox2" runat="server" >< /asp:TextBox >< br / > < br / > < asp:Button ID="Button1" runat="server" Text="Add User to Role" OnClick="Button1_Click" / >< br / > < br / > < asp:Label ID="Label1" runat="server" >< /asp:Label >< /div > < /form > < /body > < /html > C# < %@ Page Language="C#" % > < script runat="server" > protected void Button1_Click(object sender, EventArgs e) { try { Roles.AddUserToRole(TextBox1.Text, TextBox2.Text); Continued 659 Evjen c13.tex V2 - 01/28/2008 2:36pm Page 660 Chapter 13: Extending the Provider Model Label1.Text = "User successfully added to role"; } catch (Exception ex) { Label1.Text = ex.Message.ToString(); } } < /script > In this example, two text boxes are provided. The first asks for the username and the second asks for the role to add the user to. The code for the button click event uses the Roles.AddUserToRole() method. Because you built the provider, you know that an error is thrown if there is an attempt to add a user t o the Administrator role. This attempt is illustrated in Figure 13-8. Figure 13-8 In this case, there was an attempt to add User2 to the Administrator role. This, of course, throws an error and returns the e rror message that is defined in the provider. Summary From this chapter and the last chapter, you got a good taste of the provider model and what it means to the ASP.NET 3.5 applications you build today. Although a lot of providers are available to you out of the box to use for interacting with one of the many systems provided in ASP.NET, you are not limited to just these providers. You definitely can either build your own providers or even extend the functionality of the providers already present in the system. This chapter looked at both of these scenarios. First, you built your own provider to use the membership system with an XML data store for the user data, and then you worked through an example of extending the SqlRoleProvider class (something already present in ASP.NET) to change t he underlying behavior of this provider. 660 Evjen c14.tex V2 - 01/28/2008 2:39pm Page 661 Site Navigation The Web applications that you develop generally have more than a single page to them. Usually you create a number of Web pages that are interconnected in some fashion. If you also build the navigation around your collection of pages, you make it easy for the end user to successfully work through your application in a straightforward manner. Currently, you must choose among a number of different ways to expose the paths through your application to the end user. The difficult task of site navigation is compounded when you continue to add pages to the o verall application. The present method for building navigation within Web applications is to sprinkle pages with hyperlinks. Hyperlinks are generally added to Web pages by using include files or user controls. They can also be directly hard-coded onto a page so that they appear in the header or the sidebar of the page being viewed. The difficulties in working with navigation become worse when you move pages around or change page names. Sometimes developers are forced to go to each and every page in the application just to change some aspect of the navigation. ASP.NET 3.5 tackles this problem by p roviding a navigation system that makes it quite trivial to manage how end users work through the applications you create. This capability in ASP.NET is complex; but the great thing is that it can be as simple as you need it to be, or you can actually get in deep and control every aspect of how it works. The site navigation system includes the capability to define your entire site in an XML file that is called a site map. After you define a site map, you can work with it programmatically using the SiteMap class. Another aspect of the sitemap capability available in ASP.NET is a data provider that is specifically developed to work with site map files and to bind them to a series of navigation-based server controls. This chapter looks at all these components in the ASP.NET 3.5 navigation system. The following section introduces site maps. Evjen c14.tex V2 - 01/28/2008 2:39pm Page 662 Chapter 14: Site Navigation XML-Based Site Maps Although a site map is not a required element (as you see later), one of the common first steps you take in working with the ASP.NET 3.5 navigation system is building a site map for your application. A site map is an XML description of your site’s structure. You use this site map to define the navigational structure of all the pages in your application and how they relate to one another. If you do this according to the ASP.NET site map standard, you can then inter- act with this navigation information using either the SiteMap class or the SiteMapDataSource control. By using the SiteMapDataSource control, you can then b ind the information in the site map file to a variety of data-binding controls, including the navigation server controls provided by ASP.NET. To create a site map file for your application, add a site map or an XML file to your application. When asked, you name the XML file Web.sitemap ; this file is already in place if you select the Site Map option. The file is named Web and has the file extension of .sitemap . Take a look at an example of a .sitemap file illustrated here in Listing 14-1. Listing 14-1: An example of a Web.sitemap file <?xml version="1.0" encoding="utf-8" ?> <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" > <siteMapNode title="Home" description="Home Page" url="Default.aspx"> <siteMapNode title="News" description="The Latest News" url="News.aspx"> <siteMapNode title="U.S." description="U.S. News" url="News.aspx?cat=us" /> <siteMapNode title="World" description="World News" url="News.aspx?cat=world" /> <siteMapNode title="Technology" description="Technology News" url="News.aspx?cat=tech" /> <siteMapNode title="Sports" description="Sports News" url="News.aspx?cat=sport" /> </siteMapNode> <siteMapNode title="Finance" description="The Latest Financial Information" url="Finance.aspx"> <siteMapNode title="Quotes" description="Get the Latest Quotes" url="Quotes.aspx" /> <siteMapNode title="Markets" description="The Latest Market Information" url="Markets.aspx"> <siteMapNode title="U.S. Market Report" description="Looking at the U.S. Market" url="MarketsUS.aspx" /> <siteMapNode title="NYSE" description="The New York Stock Exchange" url="NYSE.aspx" /> </siteMapNode> <siteMapNode title="Funds" description="Mutual Funds" url="Funds.aspx" /> </siteMapNode> <siteMapNode title="Weather" description="The Latest Weather" url="Weather.aspx" /> </siteMapNode> </siteMap> 662 Evjen c14.tex V2 - 01/28/2008 2:39pm Page 663 Chapter 14: Site Navigation So what does this file give you? Well, it gives you a logical structure that ASP.NET can now use in the rest of the navigation system it provides. Next, this chapter examines how this file is constructed. The root node of this XML file is a < siteMap > element. Only one < siteMap > element can exist in the file. Within the < siteMap > element, there is a single root < siteMapNode > element. This is gen- erally the start page of the application. In the case of the file in Listing 14-1, the root < siteMapNode > points to the Default.aspx page, the start page: <siteMapNode title="Home" description="Home Page" url="Default.aspx"> The following table describes the most common attributes in the < siteMapNode > element. Attribute Description title The title attribute provides a textual description of the link. The String value used here is the text used for the link. description The description attribute not only reminds you what the link is for, but it is also used for the ToolTip attribute on the link. The ToolTip attribute is the yellow box that shows up next to the link when the end user hovers the cursor over the link for a couple of seconds. url The url attribute describes where the file is located in the solution. If the file is in the root directory, simply use the file name, such as "Default.aspx" .Ifthefileis located in a subfolder, be sure to include the folders in the String value used in this attribute. For example, ‘‘ MySubFolder/Markets.aspx ’’. After you have the first < siteMapNode > in place, you can then nest as many additional < siteMapNode > elements as you need within the root < siteMapNode > element. You can also create additional link-levels by creating child < siteMapNode > elements for any parent < siteMapNode > in the structure. The example in Listing 14-1 gives the application the following navigational structure: Home News U.S. World Technology Sports Finance Quotes Markets U.S. Market Report NYSE Funds Weather You can see that this structure goes down three levels in some places. One of the easiest places to use this file is with the SiteMapPath server control that comes with ASP.NET. The SiteMapPath server control in ASP.NET is built to work specifically with the .sitemap files. 663 Evjen c14.tex V2 - 01/28/2008 2:39pm Page 664 Chapter 14: Site Navigation SiteMapPath Server Control It is quite easy to use the .sitemap file you just created with the SiteMapPath server control provided with ASP.NET. You can find this control in the Navigation section of the Visual Studio 2008 IDE. The SiteMapPath control creates navigation functionality that you once might have either created your- self or have seen elsewhere in Web pages on the Internet. The SiteMapPath control creates what some refer to as breadcrumb navigation. This is a linear path defining where the end user is in the navigation structure. The Reuters.com Web site, shown in Figure 14-1, uses this type of navigation. A black box shows the breadcrumb navigation used on the page. Figure 14-1 The purpose of this type of navigation is to show end users where they are in relation to the rest of the site. Traditionally, coding this kind of navigation has been tricky, to say the least; but now with the introduction of the SiteMapPath server control, you should find coding for this type of navigation a breeze. You should first create an application that has the Web.sitemap file created in Listing 14-1. From there, create a WebForm called MarketsUS.aspx . This file is defined in the Web.sitemap file as being on the lowest tier of files in the application. 664 Evjen c14.tex V2 - 01/28/2008 2:39pm Page 665 Chapter 14: Site Navigation The SiteMapPath control is so easy to work with that it doesn’t even require a data source control to hook it up to the Web.sitemap file where it infers all its information. All you do is drag-and-drop a SiteMapPath control onto your MarketsUS.aspx page. In the end, you should have a page similar to the one shown in Listing 14-2. Listing 14-2: Using the Web.sitemap file with a SiteMapPath s erver control <%@ Page Language="VB" %> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Using the SiteMapPath Server Control</title> </head> <body> <form id="form1" runat="server"> <asp:SiteMapPath ID="Sitemappath1" runat="server"> </asp:SiteMapPath> </form> </body> </html> Not much to it, is there? It really is that easy. Run this page and you see the results shown in Figure 14-2. Figure 14-2 This screenshot shows that you are on the U.S. Market Report page at MarketsUS.aspx .Asanenduser, you can see that this page is part of the Markets section of the site; Markets, in turn, is part of the Finance section of the site. With breadcrumb navigation, end users who understand the structure of the site and their place in it can quickly select the links to navigate to any location in the site. If you hover your mouse over the Finance link, you see a tooltip appear after a couple of seconds, as shown in Figure 14-3. 665 Evjen c14.tex V2 - 01/28/2008 2:39pm Page 666 Chapter 14: Site Navigation Figure 14-3 This tooltip, which reads The Latest Financial Information , comes from the description attribute of the < siteMapNode > element in the Web.sitemap file. <siteMapNode title="Finance" description="The Latest Financial Information" url="Finance.aspx"> The SiteMapPath control works automatically requiring very little work on your part. You just add the basic control to your page, and the control automatically creates the breadcrumb navigation you have just seen. However, you can use the properties discussed in the following sections to modify the appearance and behavior of the control. The PathSeparator Property One important style property for the SiteMapPath control is the PathSeparator property. By default, the SiteMapPath control uses a greater than sign ( >) to separate the link elements. You can change this by reassigning a new value to the PathSeparator property. Listing 14-3 illustrates the use of this property. Listing 14-3: Changing the PathSeparator value <asp:SiteMapPath ID="Sitemappath1" runat="server" PathSeparator=" | "> </asp:SiteMapPath> Or <asp:SiteMapPath ID="Sitemappath1" runat="server"> <PathSeparatorTemplate> | </PathSeparatorTemplate> </asp:SiteMapPath> The SiteMapPath control in this example uses the pipe character ( | ), which is found above the Enter key. When it is rendered, you get the results shown in Figure 14-4. As you can see, you can use either the PathSeparator attribute or the < PathSeparatorTemplate > ele- ment within the SiteMapPath control. 666 . typing in a role other than the Administrator or Manager role gives you the results presented in Figure 13- 7. Figure 13- 7 658 Evjen c 13. tex V2 - 01/28/2008 2 :36 pm Page 659 Chapter 13: Extending. construct a simple ASP. NET page that includes a TextBox, Button, and Label server control. The page should appear as shown in Listing 13- 23. Listing 13- 23: Using Roles.CreateRole() VB < %@ Page. By using the SiteMapDataSource control, you can then b ind the information in the site map file to a variety of data-binding controls, including the navigation server controls provided by ASP. NET. To