<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://aspadvice.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>.Net Discoveries</title><link>http://aspadvice.com/blogs/net_discoveries/default.aspx</link><description>An attempt to pass along some answers I have discovered in my .Net coding.</description><dc:language>en</dc:language><generator>CommunityServer 2.1 (Build: 60809.935)</generator><item><title>Filling in the Gaps - Problem Design Solution 3.5 - Part 1</title><link>http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx</link><pubDate>Fri, 19 Mar 2010 19:26:42 GMT</pubDate><guid isPermaLink="false">e709ad4c-0c15-48eb-915e-c462c6e85445:61585</guid><dc:creator>Yougotiger</dc:creator><slash:comments>0</slash:comments><comments>http://aspadvice.com/blogs/net_discoveries/comments/61585.aspx</comments><wfw:commentRss>http://aspadvice.com/blogs/net_discoveries/commentrss.aspx?PostID=61585</wfw:commentRss><wfw:comment>http://aspadvice.com/blogs/net_discoveries/rsscomments.aspx?PostID=61585</wfw:comment><description>&lt;p class="MyHeadings"&gt;Prologue&lt;/p&gt;  &lt;p&gt;**Author's Note - I waited until I had both parts of this post put together before posting, which gave me some time to read a little in some of the other chapters. Things seem to have improved in readability some in them. I want to emphasize again that I'm not here to bash the book, rather to provide some of the missing information.&lt;/p&gt;  &lt;p&gt;About the time I started this blog, I purchased an AWESOME programming book - &lt;a href="http://www.amazon.com/s/ref=nb_ss_0_12?url=search-alias%3Daps&amp;amp;field-keywords=asp.net+2.0+website+programming+problem+-+design+-+solution&amp;amp;sprefix=asp.net+2.0+" target="_blank"&gt;ASP.Net 2.0 Website Programming: Problem - Design - Solution&lt;/a&gt;. A very highly praised book, and for good reason, it's fantastic! (in fact, do you see a resemblance between my blog sections and the the book's title?) Recently a newer &lt;a href="http://www.amazon.com/ASP-NET-3-5-Website-Programming-Programmer/dp/0470187581/ref=sr_1_3?ie=UTF8&amp;amp;s=books&amp;amp;qid=1262906674&amp;amp;sr=8-3" target="_blank"&gt;ASP.Net 3.5 edition&lt;/a&gt; was announced, and I practically pre-ordered it (which I've never done with any book before) with the anticipation that it would be as good as the previous edition. Quite frankly, having read the first 3 chapters, I am pretty disappointed. Specifically, I've found that rather than being strictly Problem Design Solution, it's kind of Problem, Design/Solution, not quite enough Solution. The code for the solution has been kind of hard to follow since it is SO mixed into the explanation given in the design section. Also I've had a hard time figuring out where the author intends to put code (i.e. what files and in what folders). I have found that &lt;a href="http://p2p.wrox.com/book-asp-net-3-5-website-programming-problem-design-solution-526/" target="_blank"&gt;I'm not the only one&lt;/a&gt; with this problem, so something's not quite right. In the interest of fairness, I still haven't made it past chapter 3 so maybe it gets better in chapter 4 or 5, however I'd like to get this working before I move on to subsequent chapters.&lt;/p&gt;  &lt;p&gt;I think that like many others in the &lt;a href="http://p2p.wrox.com/book-asp-net-3-5-website-programming-problem-design-solution-526/" target="_blank"&gt;book's official forum&lt;/a&gt;, I was expecting (like in the previous version) to walk trough the book and create a working website. The author made it clear in the forums that this isn't the case, &lt;a href="http://p2p.wrox.com/book-asp-net-3-5-website-programming-problem-design-solution/77355-solution-section-confusing-sometimes.html#post250826" target="_blank"&gt;&amp;quot;the book is not intended to be a follow along and create the site step by step book. There's not enough room...&amp;quot;&lt;/a&gt; Personally I disagree. I feel the book could have done exactly that while remaining a reasonable length. Also I would have liked to see the project code download have a project for each chapter (where each chapter's project takes all the code from previous chapters and builds from there), so that we can watch the progression of the code as we go through the book.&lt;/p&gt;  &lt;p&gt;Having said that, I'm not here specifically to bash the newer version of the book, rather I thought I'd fill in some of the gaps and document how to do some of the things I felt were missing or poorly described. I hope to fill in some of the gaps - like what file to put xyz code in, and in what folder/solution to put that code file in. I expect that I may do a couple of posts related to this topic (in fact this chapter. (*Note: Since I'm already past chapter 2, so I don't expect that I'll go back and fill in any holes there...))&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Problem&lt;/p&gt;  &lt;p&gt;When I finished reading chapter 3, I found that using the code in the Solution section I had some major holes in my solution. Specifically, I found the following that I will address in this post (others will follow). I needed:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A table definition for the SiteMap data (what are the data types?). &lt;/li&gt;    &lt;li&gt;To generate an Entity Model for the SiteMap data. &lt;/li&gt;    &lt;li&gt;A Base Repository class. &lt;/li&gt;    &lt;li&gt;Some code for our Helpers class module. &lt;/li&gt;    &lt;li&gt;A SiteMap repository class. &lt;/li&gt;    &lt;li&gt;An IBaseEntity interface. &lt;/li&gt;    &lt;li&gt;A partial class extending our SiteMapInfo object generated by out Entity Model wizard. &lt;/li&gt;    &lt;li&gt;A partial class extending our SiteMapEntity generated by our Entity Model wizard. &lt;/li&gt;    &lt;li&gt;A BeerHouseDataException class. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Hopefully I'll be able to provide a little of this for you so that you don't have to go around figuring out stuff only by looking through the source code files like I have.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Solution&lt;/p&gt;  &lt;p&gt;Let's start at the top and work down (or at the beginning and work backwards?)&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;A table Definition for the SiteMap Data&lt;/p&gt;  &lt;p&gt;One of the first things that sticks out is that there isn't really a definition of the SiteMap table in the database. There was mention in the forums that there are pictures of the SiteMap table in the book on pages 80 and 125, but this is lacking in some detail as it doesn't provide datatypes, just the column names. I found that the database files were included in a separate download and that they are SQL Server 2008 version (meaning they can't be run with SQL Server 2005). SO if you want to access the files yourself, you can:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Download and install SQL Server 2008 Express. &lt;/li&gt;    &lt;li&gt;Download and install SQL Server Management Studio Express 2008, you can't connect using the 2005 version (which is much harder than it sounds - and MUCH harder than it ought to be - just read the community content &lt;a href="http://msdn.microsoft.com/en-us/library/ms365247.aspx" target="_blank"&gt;here&lt;/a&gt;). &lt;/li&gt;    &lt;li&gt;Attach your DB files and then find the definitions. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Or, you can just use this script to generate your table (I'm using SQL Server 2005 instead of 2008 on my machine) or to at least get your type definitions etc. I generated this script from the database in the code download. While the code download is SQL Server 2008, I found that this script successfully creates the table in my 2005 Server. The SiteMap table is defined as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;USE [TheBeerHouseVB]      &lt;br /&gt;GO       &lt;br /&gt;      &lt;br /&gt;/****** Object:&amp;#160; Table [dbo].[SiteMap]&amp;#160;&amp;#160;&amp;#160; Script Date: 01/07/2010 16:41:55 ******/       &lt;br /&gt;SET ANSI_NULLS ON       &lt;br /&gt;GO       &lt;br /&gt;      &lt;br /&gt;SET QUOTED_IDENTIFIER ON       &lt;br /&gt;GO       &lt;br /&gt;      &lt;br /&gt;CREATE TABLE [dbo].[SiteMap](       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [SiteMapId] [int] IDENTITY(1,1) NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [URL] [nvarchar](500) NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [RealURL] [nvarchar](500) NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Title] [nvarchar](256) NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Keywords] [nvarchar](500) NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Description] [nvarchar](200) NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Roles] [nvarchar](100) NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Parent] [int] NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [URLId] [int] NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [URLType] [nvarchar](50) NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [NodeType] [int] NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [SortOrder] [int] NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Active] [bit] NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [DateAdded] [datetime] NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [AddedBy] [nvarchar](50) NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [DateUpdated] [datetime] NOT NULL,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [UpdatedBy] [nvarchar](50) NOT NULL,       &lt;br /&gt;CONSTRAINT [PK_SiteMap] PRIMARY KEY CLUSTERED       &lt;br /&gt;(       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [SiteMapId] ASC       &lt;br /&gt;)WITH (PAD_INDEX&amp;#160; = OFF, STATISTICS_NORECOMPUTE&amp;#160; = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS&amp;#160; = ON, ALLOW_PAGE_LOCKS&amp;#160; = ON) ON [PRIMARY]       &lt;br /&gt;) ON [PRIMARY]       &lt;br /&gt;      &lt;br /&gt;GO       &lt;br /&gt;      &lt;br /&gt;ALTER TABLE [dbo].[SiteMap] ADD&amp;#160; CONSTRAINT [DF_SiteMap_Parent]&amp;#160; DEFAULT ((0)) FOR [Parent]       &lt;br /&gt;GO       &lt;br /&gt;      &lt;br /&gt;ALTER TABLE [dbo].[SiteMap] ADD&amp;#160; CONSTRAINT [DF_SiteMap_URLId]&amp;#160; DEFAULT ((0)) FOR [URLId]       &lt;br /&gt;GO       &lt;br /&gt;      &lt;br /&gt;ALTER TABLE [dbo].[SiteMap] ADD&amp;#160; CONSTRAINT [DF_SiteMap_NodeType]&amp;#160; DEFAULT ((1)) FOR [NodeType]       &lt;br /&gt;GO       &lt;br /&gt;      &lt;br /&gt;ALTER TABLE [dbo].[SiteMap] ADD&amp;#160; CONSTRAINT [DF_SiteMap_SortOrder]&amp;#160; DEFAULT ((100)) FOR [SortOrder]       &lt;br /&gt;GO       &lt;br /&gt;      &lt;br /&gt;ALTER TABLE [dbo].[SiteMap] ADD&amp;#160; CONSTRAINT [DF_SiteMap_Active]&amp;#160; DEFAULT ((1)) FOR [Active]       &lt;br /&gt;GO       &lt;br /&gt;      &lt;br /&gt;ALTER TABLE [dbo].[SiteMap] ADD&amp;#160; CONSTRAINT [DF_SiteMap_DateAdded]&amp;#160; DEFAULT (getdate()) FOR [DateAdded]       &lt;br /&gt;GO       &lt;br /&gt;      &lt;br /&gt;ALTER TABLE [dbo].[SiteMap] ADD&amp;#160; CONSTRAINT [DF_SiteMap_DateUpdated]&amp;#160; DEFAULT (getdate()) FOR [DateUpdated]       &lt;br /&gt;GO&lt;/p&gt; &lt;/blockquote&gt;  &lt;p class="MySubHeadings"&gt;Generate an Entity Model for the SiteMap Data&lt;/p&gt;  &lt;p&gt;I actually found that if I went back and implemented some the DESIGN section, there is a pretty decent walk through of creating the Entity Model. There are a few missing pieces I'll add though, and I'll try to point those out as I go (for future reference, these will be marked with an &lt;strong&gt;*Gap-Filled*&lt;/strong&gt; designation).&lt;/p&gt;  &lt;p&gt;First, where should the Entity Model go? I found that the author has this as part of the BLL DLL project (say that 10 times fast). Specifically, it goes in a folder called 'Navigation'. So to create our SiteMap Entity Model, do the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;*Gap-Filled* &lt;/strong&gt;Add a new folder to your TBHBLL project's root node and name this folder 'Navigation'. &lt;/li&gt;    &lt;li&gt;Right-Click the Navigation folder and select 'Add'-&amp;gt;'New Item'. &lt;/li&gt;    &lt;li&gt;From the list select 'ADO.Net Entity Data Model (it may be easier to find if you select 'Data' from the list on the left). Name it 'SiteMapModel' and click 'Add'. &lt;/li&gt;    &lt;li&gt;Select 'Generate from database' and click Next. (Note: originally I created a database in my App_Data folder, but found that making any changes to the DB was a major pain in the neck so I opted to nuke it an put it in an external DB, just for sake of easy of working with the DB). &lt;/li&gt;    &lt;li&gt;Select your DB, or if you aren't using the App_Data folder to house your data, click 'New Connection...'. From there, you can create your data connection to your DB. Notice that this creates a connection string for your entity. You'll want to copy this for later use (put it somewhere safe, make your life easier). &lt;/li&gt;    &lt;li&gt;Before clicking next, you'll want to change the setting at the bottom 'Save entity connection settings in app.config as:' to 'SiteMapEntities'. Then click next. &lt;/li&gt;    &lt;li&gt;Now you should select the 'SiteMap' table as the object to include in your model and change the 'Model Namespace' to 'SiteMapModel'. &lt;/li&gt;    &lt;li&gt;Click Finish. &lt;/li&gt;    &lt;li&gt;Once the model is created, it will open a new 'SiteMapModel.edmx' file. We want to make a couple changes here. &lt;/li&gt;    &lt;li&gt;We want to change the name of our model to 'SiteMapInfo' rather than 'SiteMap' so as to &lt;strike&gt;not be&lt;/strike&gt; to be less confusing. Double click the name 'SiteMap' and rename it to 'SiteMapInfo' (alternately, you can select it and use the Properties window). &lt;/li&gt;    &lt;li&gt;Select the 'Active' DB column down in the list and select the properties window. Change the 'Default Value' to 'True'. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;You'll see that this basically creates a file containing two classes: 1. your actual entity object class (SiteMapInfo) and your Data Access Layer class (SiteMapEntities). We'll be extending BOTH these classes later on in this post. Go ahead and close your new SiteMapModel.edmx file and any of the new property windows that you don't want lingering around (I set them to autohide).&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;A BaseRepository Class&lt;/p&gt;  &lt;p&gt;This one is a bit more tricky. I don't feel that it was fully fleshed out in the book. Looking through the source code and through the book, we find that all the repositories we'll be creating inherit from a BaseRepository class. Let's begin by creating this class. &lt;strong&gt;&lt;/strong&gt;Start by creating a BaseRepository file (on page 89):&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;In the root of your BLL project, create a new folder called 'Context'.&lt;strong&gt;*Gap-Filled*&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;Add a new class to your 'Context' folder and name it 'BaseRepository.vb'. &lt;/li&gt;    &lt;li&gt;We need to change the class to be an interface so, change the class definition clause from 'Public Class BaseRepository' by adding the 'MustInherit' keyword. &lt;/li&gt;    &lt;li&gt;Make the class implement the IDisposable interface by adding 'Implements IDisposable' after the definition. &lt;/li&gt;    &lt;li&gt;When you press enter, you'll notice (at least I did) that it actually fleshes out the 'Dispose' subroutines. According to the book, we want those to be stubs only. As we'll define these each time in our repositories. To do this, &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;*Gap-Filled* &lt;/strong&gt;Add the 'MustOverride' keyword to the subroutine's first line. When you do that, all the subsequent stuff in the subroutine will become extraneous and can be removed so that the subroutine is ONLY one line, just defining it. The class should look like this (note: I've added the imports that we'll need before we're done already):       &lt;br /&gt;      &lt;br /&gt;      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Imports System.Web          &lt;br /&gt;Imports System.Web.Caching           &lt;br /&gt;Imports System.Security.Principal           &lt;br /&gt;Imports System.Configuration           &lt;br /&gt;          &lt;br /&gt;Namespace BLL           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public MustInherit Class BaseRepository           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Implements IDisposable&amp;#160; &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Private disposedValue As Boolean = False&amp;#160; ' To detect redundant calls           &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ' IDisposable           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Protected MustOverride Sub Dispose(ByVal disposing As Boolean)           &lt;br /&gt;          &lt;br /&gt;#Region &amp;quot; IDisposable Support &amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Public MustOverride Sub Dispose() Implements IDisposable.Dispose           &lt;br /&gt;          &lt;br /&gt;#End Region&amp;#160; &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Class           &lt;br /&gt;          &lt;br /&gt;End Namespace&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;*Gap-Filled* &lt;/strong&gt;If you're continuing to follow in the book, skip the stuff at the bottom of page 89-90. That's that's an example of what we'll do when we inherit from the BaseRepository. Skip down to the 2nd code listing and let's continue adding to our class. Next we add a couple of constants:       &lt;br /&gt;      &lt;br /&gt;      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Public Const DefPageSize As Integer = 50          &lt;br /&gt;Protected Const MAXROWS As Integer = Integer.MaxValue&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;Then we want to add some properties that will be part of each of our repositories:      &lt;br /&gt;      &lt;br /&gt;      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;'These need to be definable in config and stored in app cache          &lt;br /&gt;Private _enableCaching As Boolean = True           &lt;br /&gt;Private _cacheDuration As Integer = 0 Public           &lt;br /&gt;          &lt;br /&gt;Property EnableCaching() As Boolean           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _enableCaching           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As Boolean)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _enableCaching = value           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set           &lt;br /&gt;End Property           &lt;br /&gt;Public Property CacheDuration() As Integer           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _cacheDuration           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As Integer)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _cacheDuration = value           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set           &lt;br /&gt;End Property           &lt;br /&gt;          &lt;br /&gt;Private _cacheKey As String = &amp;quot;CacheKey&amp;quot;           &lt;br /&gt;Public Property CacheKey() As String           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _cacheKey           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _cacheKey = value           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set           &lt;br /&gt;End Property&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;Somehow, I thought that the code section at the bottom of page 91 was a demonstration of using the Cache code, however upon further investigation, I was incorrect. It also belongs to our BaseRepository class. Add the following to your class:      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Protected Shared ReadOnly Property Cache() As Cache          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return HttpContext.Current.Cache           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get           &lt;br /&gt;End Property           &lt;br /&gt;          &lt;br /&gt;Protected Shared Sub CacheData(ByVal key As String, _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal data As Object, ByVal iDuration As Integer)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If Not IsNothing(data) Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Cache.Insert(key, data, Nothing, _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DateTime.Now.AddSeconds(iDuration), TimeSpan.Zero)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;End Sub           &lt;br /&gt;          &lt;br /&gt;Protected Sub PurgeCacheItems(ByVal prefix As String)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; prefix = prefix.ToLower()           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim itemsToRemove As New List(Of String)&amp;#160;&amp;#160; &lt;br /&gt;          &lt;br /&gt;&amp;#160; Dim enumerator As IDictionaryEnumerator = Cache.GetEnumerator()           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; While enumerator.MoveNext           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If enumerator.Key.ToString().ToLower().StartsWith(prefix) Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; itemsToRemove.Add(enumerator.Key.ToString())           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End While&amp;#160; &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; For Each itemToRemove As String In itemsToRemove           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Cache.Remove(itemToRemove)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Next           &lt;br /&gt;End Sub &lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;One note of deviation from the book: if you notice, the CacheData method takes an addition parameter not mentioned in the book. The code download adds an integer parameter called vDuration (which I changed to iDuration).&lt;strong&gt; &lt;/strong&gt;This is used when caching the data to indicate how long it should live. &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;       &lt;br /&gt;      &lt;br /&gt;We then add the connectionString stuff to our class:       &lt;br /&gt;      &lt;br /&gt;      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Private _connectionString As String = &amp;quot;Set the ConnectionString&amp;quot;          &lt;br /&gt;Public Property ConnectionString() As String           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _connectionString           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _connectionString = value           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set           &lt;br /&gt;End Property           &lt;br /&gt;          &lt;br /&gt;Protected Function GetActualConnectionString() As String           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return ConfigurationManager.ConnectionStrings _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (ConnectionString).ConnectionString           &lt;br /&gt;End Function           &lt;br /&gt;&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p class="MySubHeadings"&gt;Some Code for our Helpers Class&lt;/p&gt;  &lt;p&gt;If you follow the book, you'll notice a section in the middle of page 93 with code for three properties (CurrentUser, CurrentUserName and CurrentUserIP). There is a discrepancy between this code from the book and the code from the download. Basically the code here in the book belongs in our Helpers class. The repository DOES define these three properties, however, they call to the Helpers class to retrieve the information. I am unsure why the BaseRepository would need this if we already define them in the Helpers class (and in fact GET the data directly from the Helpers class), but they are in the BaseRepository.&lt;/p&gt;  &lt;p&gt;All discussion of that aside, the code in the middle of page 93, at least according to the code download actually goes in our Helpers class (created in chapter 2). Take a break from your BaseRepository class and add the following to your Helpers class &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Imports System.Security.Principal      &lt;br /&gt;      &lt;br /&gt;Protected Shared ReadOnly Property CurrentUser() As IPrincipal       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return HttpContext.Current.User       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property       &lt;br /&gt;      &lt;br /&gt;Protected Shared ReadOnly Property CurrentUserName() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim userName As String = String.Empty       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If CurrentUser.Identity.IsAuthenticated Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; userName = CurrentUser.Identity.Name       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return userName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property       &lt;br /&gt;      &lt;br /&gt;Protected Shared ReadOnly Property CurrentUserIP() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return HttpContext.Current.Request.UserHostAddress       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p class="MySubHeadings"&gt;Back to the BaseRepository Class&lt;/p&gt;  &lt;p&gt;We aren't done with the base repository class, we need to go back to the class now that we've finished our Helpers module diversion. Beginning again with the function at the bottom of page 93, we'll add the following to our BaseRepository class &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Protected Shared Function EncodeText(ByVal content As String) As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; content = HttpUtility.HtmlEncode(content)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; content = content.Replace(&amp;quot;&amp;#160; &amp;quot;, &amp;quot;&amp;amp;nbsp;&amp;amp;nbsp;&amp;quot;).Replace(&amp;quot;\n&amp;quot;, &amp;quot;&amp;lt;br&amp;gt;&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return content       &lt;br /&gt;End Function       &lt;br /&gt;      &lt;br /&gt;Protected Shared Function ConvertNullToEmptyString _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (ByVal input As String) As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If String.IsNullOrEmpty(input) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return String.Empty       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return input       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That fooled me. Reading the book I thought these two should go into the helpers module, but looking trough the code in the files, I found that they actually belong in the BaseRepository class.&lt;/p&gt;  &lt;p&gt;I also found reference to a couple methods in the BaseRepository class that I couldn't readily find in the text. Once such is the GetRandItem function. In searching out references to the BaseRepository class in other sections of the book I found a reference UTILZING this function, but not DEFINING it. As such, I'll take the time to define it here so we'll have it in our BaseRepository class. You'll recognize that it's bascially just a random number generator. Add the following function to your BaseRepository class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Function GetRandItem(ByVal min As Integer, ByVal max As Integer) As Integer      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Randomize()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return Int((max - min) * Rnd())       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Finally, we can add (and I'd consider it optional) the three properties that call our Helpers class. If you want, add the following to your BaseRepository class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Protected Shared ReadOnly Property CurrentUser() As IPrincipal      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return Helpers.CurrentUser       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property       &lt;br /&gt;      &lt;br /&gt;Protected Shared ReadOnly Property CurrentUserName() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return Helpers.CurrentUserName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property       &lt;br /&gt;      &lt;br /&gt;Protected Shared ReadOnly Property CurrentUserIP() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return Helpers.CurrentUserIP       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Again, you'll notice that they just call the properties we called in the Helpers class.&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;Creating a SiteMapRepository Class&lt;/p&gt;  &lt;p&gt;As far as I can tell, the code for the SiteMapRepository is missing from the book in a major way. The example in this section gives us some sample code for the ArticlesRepository and its related classes (categories etc) but not for the SiteMapRepository class itself. We'll jump around a little to create this and hopefully come up with something that works. Let's get started:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;We want to create a SiteMapRepository Class, this should be created in the Navigation folder &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;. &lt;/li&gt;    &lt;li&gt;This class should inherit the BaseRepository class that we just created, which will automatically give us stubs for the Dispose methods. To complete the stubs, we should go back to page 89 and pick out from the last code block to fill in our stubs. Add the following to your SiteMapRepository class's Dispose() methods:      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Public Overloads Overrides Sub Dispose()          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dispose(True)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; GC.SuppressFinalize(Me)           &lt;br /&gt;End Sub           &lt;br /&gt;          &lt;br /&gt;Private disposedValue As Boolean = False           &lt;br /&gt;Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If Not Me.disposedValue Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If disposing Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If IsNothing(_SiteMapctx) = False Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _SiteMapctx.Dispose()           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Me.disposedValue = True           &lt;br /&gt;End Sub&lt;/p&gt;     &lt;/blockquote&gt; Two items of note: 1. There is a private variable declared OUTSIDE our methods we need to create: disposedValue. 2. We'll get an undefined error regarding the _SiteMapctx object referenced in the 2nd dispose method, we need to define this.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Do do this, we can examine the code from the ArticlesRespoitory on page 94 and modify it to be our SiteMapRespository code. Add the following to your SiteMapRepository class.      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Private _SiteMapctx As SiteMapEntities          &lt;br /&gt;Public Property SiteMapctx() As SiteMapEntities           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If IsNothing(_SiteMapctx) Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _SiteMapctx = New SiteMapEntities _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (GetActualConnectionString())           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _SiteMapctx           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As SiteMapEntities)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _SiteMapctx = value           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set           &lt;br /&gt;End Property&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;At this point, the book examines the contents of a entity (see page 95-98). This helps us better understand what is going on in side the entity class. Uh, so were do you find &lt;u&gt;this&lt;/u&gt; code? (I'm digressing a little, but the code can be found in the designer.vb file for your model.edmx file. In VS.Net, this file is hidden, you have to select the button at the top of the Solution Explorer to view all files to see this file. When you select it, then you'll see a plus in front of your model.edmx file. Clicking it reveals the model.designer.vb file. This is where the content of the 'entity' class guts discussed in these pages resides &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;). &lt;/li&gt;    &lt;li&gt;There is also a discussion of the IBaseEntity interface inserted in page 98. I'll talk about that in a minute, but for the time being, let's stick with our repository just for the sake of keeping things together. &lt;/li&gt;    &lt;li&gt;So, we also need a constructor for our SiteMapRepository, this also is somewhat tucked away, it is in the BaseRespository section of the book. If you reference pg 92, you'll see a code block at the bottom of the page containing the constructors for our SiteMapRepository. Add the following to your SiteMapRespository.vb file &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;:       &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Public Sub New(ByVal sConnectionString As String)          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ConnectionString = sConnectionString           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CacheKey = &amp;quot;SiteMap&amp;quot;           &lt;br /&gt;End Sub           &lt;br /&gt;          &lt;br /&gt;Public Sub New()           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ConnectionString = Globals.Settings.DefaultConnectionStringName           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CacheKey = &amp;quot;SiteMap&amp;quot;           &lt;br /&gt;End Sub           &lt;br /&gt;&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;The next piece of the repository that I found was on page 138. There is a GetSiteMapInfoByURL function that is defined there that we can add to our repository. Add the following code to your repository:      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Public Function GetSiteMapInfoByURL(ByVal URL As String) _          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; As SiteMapInfo           &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return (From lai In SiteMapctx.SiteMapInfoSet _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Where lai.URL = URL).FirstOrDefault()           &lt;br /&gt;          &lt;br /&gt;End Function &lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;That leaves quite a few of the methods undefined (as much because we don't know what they are as anything else). So I began a search through chapter three to see if I can find any more of these methods lurking around. I found one on page 73, funny enough though, this method is added upon when we get to page 101 when we add the caching bits into it. I'll just go straight to this piece on page 101 and do it all. Add the following to your repository (note there are discrepancies between the project download code and the code in the book - such as the addition of CacheDuration):      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Private key as String = &amp;quot;SiteMapNodes&amp;quot;          &lt;br /&gt;Public Function GetSiteMapNodes() As List(Of SiteMapInfo)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim lSiteMapNodes As List(Of SiteMapInfo)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If EnableCaching AndAlso Not IsNothing(Cache(key)) Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNodes = CType(Cache(key), List(Of SiteMapInfo))           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SiteMapctx.SiteMapInfoSet.MergeOption = _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Objects.MergeOption.NoTracking           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lSiteMapNodes = (From lSiteMapNode In _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SiteMapctx.SiteMapInfoSet Order By _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNode.SortOrder).ToList()           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If EnableCaching Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CacheData(key, lSiteMapNodes, CacheDuration)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return lSiteMapNodes           &lt;br /&gt;End Function &lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;And, that's about all I can find regarding the SiteMapRespository's methods in the book. So I was forced to find the rest of them in the code download. Really, I think it's rather unfortunate the book doesn't have any of the rest of the code, but here's what I found to add &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;:       &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Private tsnKey As String = &amp;quot;TopSiteMapNodes&amp;quot;          &lt;br /&gt;Public Function GetActiveSiteMapNodes() As List(Of SiteMapInfo)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim lSiteMapNodes As List(Of SiteMapInfo)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim lActiveSiteMapKey As String = CacheKey &amp;amp; &amp;quot;_Active&amp;quot;           &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If MyBase.EnableCaching AndAlso _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Not IsNothing(Cache(lActiveSiteMapKey)) Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNodes = CType(Cache(lActiveSiteMapKey), _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; List(Of SiteMapInfo))           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Else           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNodes = (From lSiteMapNode In _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SiteMapctx.SiteMapInfoSet _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Where lSiteMapNode.Active = True Order By _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNode.SortOrder).ToList()           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If MyBase.EnableCaching Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CacheData(lActiveSiteMapKey, lSiteMapNodes, CacheDuration)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return lSiteMapNodes           &lt;br /&gt;End Function           &lt;br /&gt;          &lt;br /&gt;Public Function GetTopSiteMapNodes() As List(Of SiteMapInfo)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim lSiteMapNodes As List(Of SiteMapInfo)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If Not IsNothing(Cache(tsnKey)) Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNodes = CType(Cache(tsnKey), List(Of SiteMapInfo)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Else           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNodes = (From lSiteMapNode In _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SiteMapctx.SiteMapInfoSet _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Where lSiteMapNode.Active = True And _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNode.Parent = 0 _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Order By lSiteMapNode.SortOrder).ToList()           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CacheData(tsnKey, lSiteMapNodes, CacheDuration)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return lSiteMapNodes           &lt;br /&gt;End Function           &lt;br /&gt;          &lt;br /&gt;Public Function GetSiteMap() As List(Of SiteMapInfo)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return (From lSiteMap In SiteMapctx.SiteMapInfoSet _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Where lSiteMap.Active = True).ToList()           &lt;br /&gt;End Function           &lt;br /&gt;          &lt;br /&gt;Public Function GetSiteMapByID(ByVal SiteMapId As Integer) _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; As SiteMapInfo           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return (From lai In SiteMapctx.SiteMapInfoSet _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Where lai.SiteMapId = SiteMapId).FirstOrDefault           &lt;br /&gt;End Function           &lt;br /&gt;          &lt;br /&gt;Public Function GetSiteMapInfoByRealURL(ByVal URL As String) _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; As SiteMapInfo           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return (From lsmi In SiteMapctx.SiteMapInfoSet _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Where lsmi.RealURL = URL).FirstOrDefault()           &lt;br /&gt;End Function           &lt;br /&gt;          &lt;br /&gt;Public Function GetSiteMapCount() As Integer           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return (From lai In SiteMapctx.SiteMapInfoSet).Count()           &lt;br /&gt;End Function           &lt;br /&gt;          &lt;br /&gt;Public Function AddSiteMap(ByVal vSiteMap As SiteMapInfo) _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; As SiteMapInfo           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Try           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If vSiteMap.EntityState = EntityState.Detached Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SiteMapctx.AddToSiteMapInfoSet(vSiteMap)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MyBase.PurgeCacheItems(CacheKey)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return If(SiteMapctx.SaveChanges &amp;gt; 0, vSiteMap, Nothing)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Catch ex As Exception           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ActiveExceptions.add(CacheKey &amp;amp; &amp;quot;_&amp;quot; &amp;amp; vSiteMap.SiteMapId, ex)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return Nothing           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Try           &lt;br /&gt;End Function           &lt;br /&gt;          &lt;br /&gt;Public Function DeleteSiteMap(ByVal vSiteMap As SiteMapInfo) As Boolean           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Try           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SiteMapctx.DeleteObject(vSiteMap)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SiteMapctx.SaveChanges()           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MyBase.PurgeCacheItems(CacheKey)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return True           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Catch ex As Exception           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return False           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Try           &lt;br /&gt;End Function&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;Here's the definitive list of methods that we should have that I found from the project files (in no particular order):      &lt;br /&gt;      &lt;br /&gt;GetSiteMapInfoByURL()       &lt;br /&gt;GetSiteMapNodes()       &lt;br /&gt;GetActiveSiteMapNodes()       &lt;br /&gt;GetTopSiteMapNodes()       &lt;br /&gt;GetSiteMap()       &lt;br /&gt;GetSiteMapByID()       &lt;br /&gt;GetSiteMapInfoByRealURL()       &lt;br /&gt;GetSiteMapCout()       &lt;br /&gt;AddSiteMap()       &lt;br /&gt;DeleteSiteMap()       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Finally, if you notice you probably have an error about ActiveExceptions not being defined (in your AddSiteMap() function). This needs defined, however it is defined in the BaseRepository.vb class. So we'll go back one more time to our BaseRepository.vb class. &lt;/li&gt; &lt;/ol&gt;  &lt;p class="MySubHeadings"&gt;Back to the BaseRepository Class (Again)&lt;/p&gt;  &lt;p&gt;We've got one more property to add to our BaseRepository class so that we can track exceptions that occur. While we are using this property here in Chapter 3 in our SiteMapRepository class, it isn't actually defined until Chapter 5. The definition of this property is found on page 262 (&lt;strong&gt;*Gap-Filled*&lt;/strong&gt;). Add the following to your BaseRepository.vb class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private _activeExceptions As Dictionary(Of String, Exception)      &lt;br /&gt;Public Property ActiveExceptions() As Dictionary(Of String, Exception)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If IsNothing(_activeExceptions) Then _activeExceptions = _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; New Dictionary(Of String, Exception)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _activeExceptions       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As Dictionary(Of String, Exception))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _activeExceptions = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property       &lt;br /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p class="MySubHeadings"&gt;The IBaseEntity Interface&lt;/p&gt;  &lt;p&gt;Tucked nicely away in the discussion of entities the definition of an interface for an entity. If you blink you'll miss it. We'll use this later as the interface when we extend our entity class. To create this interface, do the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create a new 'Interfaces' folder in your BLL project &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;. &lt;/li&gt;    &lt;li&gt;In this folder add a new class and name it 'IBaseEntity'. &lt;/li&gt;    &lt;li&gt;Change the contents of the file to read as follows &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;:       &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Namespace BLL          &lt;br /&gt;&amp;#160;&amp;#160; Public Interface IBaseEntity&amp;#160; &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ReadOnly Property IsValid() As Boolean           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Property SetName() As String           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Property IsDirty() as Boolean           &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ReadOnly Property CanEdit() As Boolean           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ReadOnly Property CanRead() As Boolean           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ReadOnly Property CanDelete() As Boolean           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ReadOnly Property CanAdd() As Boolean           &lt;br /&gt;&amp;#160;&amp;#160; End Interface           &lt;br /&gt;End Namespace           &lt;br /&gt;&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;Notice that we're adding an additional Property that wasn't defined in the chapter, IsDirty. This is defined in the project files that were downloaded. &lt;/li&gt;    &lt;li&gt;That's it for IBaseEntity, we'll use it when we create entities (for example, an article, or category class). When we create the entity class, they will implement this interface. If you want to see an example of how it is implemented, look at the code block at the top of pg. 99. &lt;/li&gt; &lt;/ol&gt;  &lt;p class="MySubHeadings"&gt;Extending the SiteMapInfo Class (Originally Generated in the Model)&lt;/p&gt;  &lt;p&gt;It took me a long time to understand what's going one with some of the files in the final solution project and how they relate to each other. This piece is one of them. If you download the final project files, you'll find a file 'SiteMapNode.vb' in the Navigation folder. It took me forever to understand the relationship of this file to ANY of the others. It is an extension of the partial SiteMapInfo class that was generated in the Model file (SiteMapModel.Desiger.VB). You'll also notice that we also extend the SiteMapEntities class that is ALSO in the Model file. As I understand the difference between this two pieces, the SiteMapEntities Class is the ObjectContext class, or the data plumbing (the part that talks to the database - the Data Access Layer if you will). And the SiteMapInfo class is the actual object (or instance of an entity) created by one of the records in our database. BOTH get extended and in different code files. So with no further ado, let's extend our SiteMapInfo class to use our IBaseEntity and add definitions for the items that we created in our interface. I couldn't find code for these properties in the book, with the exception of the IsValid property I found on page 99. The rest of this came from the finished project file.&lt;/p&gt;  &lt;p&gt;So let's do the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create a new class module in your Navigation folder and name it 'SiteMapNode.vb'. &lt;/li&gt;    &lt;li&gt;We'll want to modify the name of the class so that it connects with the SiteMapInfo partial class, so rename the class that was created automatically to 'SiteMapInfo.' We also want it to implement our IBaseEntity interface as well so we'll do that at the same time. (and we'll add namespace information too). Your module should start out looking like this (I'm not showing the stubs auto created by pressing enter after the implements statement):      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Namespace BLL&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Class SiteMapInfo           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Implements IBaseEntity&amp;#160; &lt;br /&gt;          &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Class           &lt;br /&gt;End Namespace&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;Now we can define the properties in the class. All the CanXYZ properties are pretty easy to define. All we do is add a single line to each (and they're all the same). Add the following line to the CanAdd, CanDelete, CanEdit and CanRead properties:      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Return True&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;Then we can define the IsXYZ properties. These are not the same as each other. Altogether they should read like this:      &lt;br /&gt;      &lt;br /&gt;      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Dim bIsDirty As Boolean = False          &lt;br /&gt;Public Property IsDirty() As Boolean Implements IBaseEntity.IsDirty           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return bIsDirty           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As Boolean)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bIsDirty = value           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set           &lt;br /&gt;End Property           &lt;br /&gt;          &lt;br /&gt;Public ReadOnly Property IsValid() As Boolean Implements _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; IBaseEntity.IsValid           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If String.IsNullOrEmpty(URL) = False And _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; String.IsNullOrEmpty(RealURL) = False And _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; String.IsNullOrEmpty(Title) = False Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return True           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return False           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get           &lt;br /&gt;End Property           &lt;br /&gt;          &lt;br /&gt;Private _SetName As String = &amp;quot;SiteMap&amp;quot;           &lt;br /&gt;Public Property SetName() As String Implements IBaseEntity.SetName           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _SetName           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _SetName = value           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set           &lt;br /&gt;End Property&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;Finally, we want to extend a partial Sub declared in our SiteMapInfo class (in the model file) (see page 99-100). This allows us to do a little validation. Add the following Sub to your class:      &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Private Sub OnSiteMapIdChanging(ByVal value As Integer)          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If value &amp;lt; 0 Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Throw New ArgumentException(&amp;quot;The SiteMapId _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cannot be less than 0.&amp;quot;)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;End Sub &lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p class="MySubHeadings"&gt;Extending the SiteMapEntities Class (Originally Generated in the Model)&lt;/p&gt;  &lt;p&gt;On page 86 we are told that we are going to add one event handler to our SiteMapEntities class, SavingChanges. To do this, we will again leverage partial classes much as we did with OnSiteMapIdChanging in our SiteMapInfo class above. To do this, do the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Add a new class to your project, this should be added to the 'Navigation' folder and should be named 'SiteMapEntities.vb'. &lt;/li&gt;    &lt;li&gt;Add the following code to your SiteMapEntities.vb class file (from page 86)&lt;strong&gt;*Gap-Filled*&lt;/strong&gt; (Sorry for the ugly formatting, some of the lines are rather long):       &lt;blockquote&gt;       &lt;p class="CodeSnippet"&gt;Namespace BLL          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Class SiteMapEntities           &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private Sub SiteMapentities_SavingChanges( _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal sender As Object, ByVal e As System.EventArgs) _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Handles Me.SavingChanges           &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim typeEntries = (From entry In _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Me.ObjectStateManager.GetObjectStateEntries _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (EntityState.Added Or EntityState.Modified) _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Where TypeOf entry.Entity Is IBaseEntity).ToList()&amp;#160; &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For Each ose As System.Data.Objects.ObjectStateEntry _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; In typeEntries           &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim lBaseEntity As IBaseEntity = _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DirectCast(ose.Entity, IBaseEntity)&amp;#160; &lt;br /&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If lBaseEntity.IsValid = False Then           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Throw New BeerHouseDataException _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (String.Format(&amp;quot;{0} is not valid&amp;quot;, _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lBaseEntity.SetName), &amp;quot;&amp;quot;, &amp;quot;&amp;quot;)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Sub           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Class           &lt;br /&gt;End Namespace &lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;This class is used to validate the entries that will be saved. It cycles through all the Added and Modified entries and then tests them for validity. If they fail, then an exception is thrown.      &lt;br /&gt;      &lt;br /&gt;NOTE: A custom BeerHouseDataException is used here, I could not find any mention of it in Chapter 3, and it isn't listed in the index. So, I will provide it as found directly in the project files. &lt;/li&gt; &lt;/ol&gt;  &lt;p class="MySubHeadings"&gt;A BeerHouseDataException Class&lt;/p&gt;  &lt;p&gt;I found the following code for the BeerHouseDataExeception Class. This class should be created in the root of the BLL project and is named BeerHouseDataException.vb. Define our class as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Class BeerHouseDataException      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Inherits Exception&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private _propertyName As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property PropertyName() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _propertyName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _propertyName = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Property&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private _propertyValue As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property PropertyValue() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _propertyValue       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _propertyValue = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Property&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Sub New(ByVal Message As String, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal Innerexception As Exception, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal PropName As String, ByVal PropValue As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MyBase.New(Message, Innerexception)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropertyName = PropName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropertyValue = PropValue       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Sub&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Sub New(ByVal Message As String, ByVal PropName As String, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal PropValue As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Me.New(Message, Nothing, PropName, PropValue)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Sub       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Sub New(ByVal PropName As String, ByVal PropValue As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Me.New(&amp;quot;A Property of an object was improperly set&amp;quot;, Nothing, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropName, PropValue)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Sub       &lt;br /&gt;End Class&lt;/p&gt; &lt;/blockquote&gt;  &lt;p class="MyHeadings"&gt;Epilogue &lt;/p&gt;  &lt;p&gt;Well, we've actually covered quite a bit of code. I found when I read the chapter a few times that more of the code was in there than I originally thought, but that there were some CRITICAL pieces that are just plain missing.&lt;/p&gt;  &lt;p&gt;You'll also notice that there is still a lot of code missing. Since this blog posting is getting kind of long, I will continue filling gaps in this chapter in a Part 2. Some of the things that may still need addressed include: the SiteMap handler, a custom SiteMap provider and some URL rewrite code to name a few.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx&amp;amp;;subject=Filling+in+the+Gaps+-+Problem+Design+Solution+3.5+-+Part+1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx&amp;amp;;title=Filling+in+the+Gaps+-+Problem+Design+Solution+3.5+-+Part+1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx&amp;amp;title=Filling+in+the+Gaps+-+Problem+Design+Solution+3.5+-+Part+1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx&amp;amp;;title=Filling+in+the+Gaps+-+Problem+Design+Solution+3.5+-+Part+1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx&amp;amp;;title=Filling+in+the+Gaps+-+Problem+Design+Solution+3.5+-+Part+1&amp;amp;;top=1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://aspadvice.com/aggbug.aspx?PostID=61585" width="1" height="1"&gt;</description><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/Asp.net/default.aspx">Asp.net</category></item><item><title>Filling in the Gaps - Problem Design Solution 3.5 - Part 2</title><link>http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx</link><pubDate>Fri, 19 Mar 2010 18:29:58 GMT</pubDate><guid isPermaLink="false">e709ad4c-0c15-48eb-915e-c462c6e85445:61586</guid><dc:creator>Yougotiger</dc:creator><slash:comments>0</slash:comments><comments>http://aspadvice.com/blogs/net_discoveries/comments/61586.aspx</comments><wfw:commentRss>http://aspadvice.com/blogs/net_discoveries/commentrss.aspx?PostID=61586</wfw:commentRss><wfw:comment>http://aspadvice.com/blogs/net_discoveries/rsscomments.aspx?PostID=61586</wfw:comment><description>&lt;p class="MyHeadings"&gt;Prologue&lt;/p&gt;  &lt;p&gt;In a &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-1.aspx" target="_blank"&gt;previous post&lt;/a&gt;, I began dissecting the code in my ASP.Net 3.5 Website Programming: Problem - Design - Solution book attempting to fill in gaps that I found (such as where does the code in the book go and adding in code missing from the book). This is a continuation of that post, continuing in Chapter 3.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Problem&lt;/p&gt;  &lt;p&gt;In this post, I will attempt to address the missing pieces regarding:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The BasePage class. &lt;/li&gt;    &lt;li&gt;The SiteMap Provider. &lt;/li&gt;    &lt;li&gt;The SiteMap Handler. &lt;/li&gt;    &lt;li&gt;A URL Rewrite Class. &lt;/li&gt;    &lt;li&gt;An addition to our Helper Class. &lt;/li&gt;    &lt;li&gt;Configuring the ELMAH Error Logging Add-In. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So with no further ado, let's get started.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Solution&lt;/p&gt;  &lt;p&gt;The BasePage Class has a fair amount of code presented in the book. Specifically I found the following code pieces in chapter 3:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The MoveHiddenFields Property (pg 106) &lt;/li&gt;    &lt;li&gt;The MoveHiddenFieldsToBottom Function (pg 106) &lt;/li&gt;    &lt;li&gt;The OverRidden Render Subroutine (pg 107) &lt;/li&gt;    &lt;li&gt;The PrimaryKeyID Property (pg 107) &lt;/li&gt;    &lt;li&gt;The CreateMetaControl Subroutine (pg 138) &lt;/li&gt;    &lt;li&gt;The GetMetaValue Function (pg 139) &lt;/li&gt;    &lt;li&gt;The PageKeyWords Property (pg 139) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I did find, however, that we should also include a property to add content to the Description META tag. Adding this functionality is mentioned on page 121, however code is not included. It's very similar to your PageKeyWords property. This PageDescription property should be added to your BasePage class as follows &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Protected Property PageDescription() As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return GetMetaValue(&amp;quot;DESCRIPTION&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CreateMetaControl(&amp;quot;DESCRIPTION&amp;quot;, value)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I also found, mentioned on page 122, a Robots META tag. I was unable to find any listing of this code in the book or in the downloaded files. So I created my own &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;. The book mentioned that the content section of the tag could contain combinations of action (index, noindex) and directive (follow, nofollow). I created an enumeration of the six valid values (including all and none) and called the CreateMetaControl with the corresponding string values. The code is as follows &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Protected Enum RobotMetaOptions      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; IndexFollow       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; IndexNoFollow       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; NoIndexFollow       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; NoIndexNoFollow       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; All       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; None       &lt;br /&gt;End Enum       &lt;br /&gt;Protected Property PageRobotMeta() As RobotMetaOptions       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return GetMetaValue(&amp;quot;ROBOTS&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As RobotMetaOptions)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Select Case value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Case RobotMetaOptions.IndexFollow, RobotMetaOptions.All       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CreateMetaControl(&amp;quot;ROBOTS&amp;quot;, &amp;quot;index, follow&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Case RobotMetaOptions.IndexNoFollow       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CreateMetaControl(&amp;quot;ROBOTS&amp;quot;, &amp;quot;index, nofollow&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Case RobotMetaOptions.NoIndexFollow       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CreateMetaControl(&amp;quot;ROBOTS&amp;quot;, &amp;quot;noindex, follow&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Case RobotMetaOptions.NoIndexNoFollow, RobotMetaOptions.None       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CreateMetaControl(&amp;quot;ROBOTS&amp;quot;, &amp;quot;noindex, nofollow&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Select       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In looking around the web, it seems that really, the index-follow option (or all option) is redundant since that is the default action if there is no Robots META tag. I included the options just for the sake of completeness.&lt;/p&gt;  &lt;p&gt;We can also notice that there is reference on page 121 to page title information. I found that again this is added in the code download, but I didn't find reference to it in the book. &lt;strong&gt;*Gap-Filled*&lt;/strong&gt; I added the following property from the code download for PageTitle to my BasePage class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Protected Property PageTitle() As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If Not IsNothing(Master) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If Master.Page.Title = String.Empty Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return String.Empty       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return Master.Page.Title       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If Page.Title = String.Empty Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return String.Empty       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return Page.Title       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If Not IsNothing(Master) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Master.Page.Title = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Page.Title = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;There are a couple of other methods that I think may come in handy. Since I haven't read past this chapter yet, I'm not sure if they are added later as I can't find them in the index, but they are in the code download. I decided to add them just in case. I added the following to my BasePage class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public ReadOnly Property BaseUrl() As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim url As String = Me.Request.ApplicationPath       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If url.EndsWith(&amp;quot;/&amp;quot;) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return url       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return url &amp;amp; &amp;quot;/&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property       &lt;br /&gt;      &lt;br /&gt;Public ReadOnly Property FullBaseUrl() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return Me.Request.Url.AbsoluteUri.Replace( _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Me.Request.Url.PathAndQuery, &amp;quot;&amp;quot;) &amp;amp; Me.BaseUrl       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;There were also a couple that I decided NOT to add as I felt it was redundant to add them just to have them call the Helpers class. These include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;SEOFriendlyURL &lt;/li&gt;    &lt;li&gt;ConvertToHTML &lt;/li&gt;    &lt;li&gt;GetUserProfile &lt;/li&gt;    &lt;li&gt;FormatPrice &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Looking through the rest of the code, I'm thinking that some of that may be added later in the book or at least it may not apply till later so I will move on to the next class that needs work.&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;A Custom SiteMapProvider&lt;/p&gt;  &lt;p&gt;On page 125, we're informed that we should be using a custom SiteMapProvider to generate our site map. Unfortunately, we aren't given ANY code that I find on how this is done with the exception of the settings to register the provider in the web.config file. We'll come back to that piece, but first let's create the provider so we know what to register. We're told that we can get a good primer on doing this from a &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163657.aspx" target="_blank"&gt;series of 2006 MSDN articles&lt;/a&gt;. I found that some of the code comes across into our code download, and some doesn't. Also the article is in C#, so I relied heavily on the code download. Create a TBHSiteMapProvider.vb class in your 'navigation' folder &lt;strong&gt;*Gap-Filled*&lt;/strong&gt; and add the following to get started:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Class TBHSiteMapProvider      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Inherits StaticSiteMapProvider&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private Const _errmsg1 As String = &amp;quot;Missing node ID&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private Const _errmsg2 As String = &amp;quot;Duplicate node ID&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private Const _errmsg3 As String = &amp;quot;Missing parent ID&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private Const _errmsg4 As String = &amp;quot;Invalid parent ID&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private Const _errmsg5 As String = &amp;quot;Empty or missing connectionStringName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private Const _errmsg6 As String = &amp;quot;Missing connection string&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private Const _errmsg7 As String = &amp;quot;Empty connection string&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160; Private Const _errmsg8 As String = &amp;quot;Invalid sqlCacheDependency&amp;quot;&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Const _cacheDependancyName As String = &amp;quot;__SiteMapCacheDependency&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private _connect As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private _database, _table As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private _2005dependency As Boolean = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private _indexID, _indexTitle, _indexUrl, _indexDesc, indexRoles, _indexParent As Integer       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private _nodes As New Dictionary(Of Integer, SiteMapNode)(16)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private _root As SiteMapNode       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public ReadOnly _lock As Object = New Object()&amp;#160; &lt;br /&gt;      &lt;br /&gt;End Class&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This will get our class started, you may need to add import statements as the need arises, but this gets our class going. You'll notice that our class declaration gives us an error. We need to define a number of methods in this class before it will compile. So let's get started, create an Initialize method. The code IS different than on the MSDN article starting from about the half way point. Add the following to your class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Overloads Overrides Sub Initialize(ByVal name As String, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal config As NameValueCollection)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 'Verify parameters       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If IsNothing(config) Then Throw New ArgumentNullException(&amp;quot;config&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If String.IsNullOrEmpty(name) Then name = &amp;quot;TBHSiteMapProvider&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 'add default desc to config if empty       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If String.IsNullOrEmpty(config(&amp;quot;description&amp;quot;)) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; config.Remove(&amp;quot;description&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; config.Add(&amp;quot;description&amp;quot;, &amp;quot;SQL site map provider&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 'call base's initialize       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MyBase.Initialize(name, config)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If config(&amp;quot;securityTrimmingEnabled&amp;quot;) Is Nothing Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; config.Remove(&amp;quot;securityTrimmingEnabled&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If config.Count &amp;gt; 0 Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim attr As String = config.GetKey(0)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If Not String.IsNullOrEmpty(attr) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Throw New ProviderException(&amp;quot;Unrecognized attribute: &amp;quot; &amp;amp; attr)&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We also need to add one of the required methods BuildSiteMap. This method is substantially changed from the one in the MSDN article, so I pulled it from the downloaded code. However, this version used two other methods that haven't been created yet. We'll start with those methods and then come back to the BuildSiteMap. Add the following two methods to your class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Function CreateSiteMapNodeFromSiteMapEntity(ByVal node As _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SiteMapInfo) As SiteMapNode       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim roles As String = If(node.Roles, Nothing)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 'if roles were specified, turn the list into a string array       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim roleList As String() = Nothing       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If Not String.IsNullOrEmpty(roles) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; roleList = roles.Split(New Char() {&amp;quot;,&amp;quot;c, &amp;quot;;&amp;quot;c}, 512)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 'create SiteMapNode       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim _node As New SiteMapNode(Me, node.SiteMapId.ToString(), _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; node.URL, node.Title, node.Description, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; roleList, Nothing, Nothing, Nothing)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 'record node in the _nodes directory       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; _nodes.Add(node.SiteMapId, _node)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return _node       &lt;br /&gt;End Function       &lt;br /&gt;      &lt;br /&gt;Private Sub AddChildNodes(ByVal vParentNode As SiteMapNode, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal SiteMapId As Integer)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim lChildNodes As List(Of SiteMapInfo) = (From lChildren In _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNodes Where lChildren.Parent = SiteMapId).ToList()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; For Each lChildNode As SiteMapInfo In lChildNodes       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim lNode As SiteMapNode = _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CreateSiteMapNodeFromSiteMapEntity(lChildNode)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AddNode(lNode, vParentNode)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AddChildNodes(lNode, lChildNode.SiteMapId)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Next       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You'll notice if you look at the MSDN article, that they aren't included there so they are newly created for our project from the code download. Now that they're defined, we're ready to add the BuildSiteMap method:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Protected lSiteMapNodes As List(Of SiteMapInfo)      &lt;br /&gt;Public Overrides Function BuildSiteMap() As SiteMapNode       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SyncLock _lock       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If _root IsNot Nothing Then Return _root       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Using lSiteMapContext As New SiteMapRepository       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNodes = lSiteMapContext.GetSiteMapNodes()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If lSiteMapNodes.Count &amp;gt; 0 Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim node As SiteMapInfo = (From lSiteMapNode In _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNodes Where lSiteMapNode.Parent = 0).FirstOrDefault       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If Not IsNothing(node) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _root = CreateSiteMapNodeFromSiteMapEntity(node)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AddNode(_root, Nothing)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AddChildNodes(_root, node.SiteMapId)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Using       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _root       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End SyncLock       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If you look at the errors, you'll see that we still have to define another overridden function, GetRootNodeCore. Again, we'll go to the code download since it isn't in the article or the book. Add the following to your class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Protected Overloads Overrides Function GetRootNodeCore() As SiteMapNode      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SyncLock _lock       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BuildSiteMap()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _root       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End SyncLock       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It's a pretty simple function, but necessary. The provider also needs to be registered in the web.config file. To do this, add the following to your web.config file, it should go somewhere in your &amp;lt;system.web&amp;gt; element:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;siteMap defaultProvider=&amp;quot;TBHSiteMapProvider&amp;quot; enabled=&amp;quot;true&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;providers&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;add name=&amp;quot;TBHSiteMapProvider&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; type=&amp;quot;TheBeerHouse.TBHSiteMapProvider&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; securityTrimmingEnabled=&amp;quot;true&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/providers&amp;gt;       &lt;br /&gt;&amp;lt;/siteMap&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;There are two other methods in the downloaded code, however I'm not sure exactly what they do, I can't that they are called/referenced anywhere else. Since I don't see where they are used (at least at this point), I haven't included them.&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;A SiteMapHandler Class&lt;/p&gt;  &lt;p&gt;This class is a handler that returns the sitemap.xml file used by search engine spiders so that our site can be easily indexed. This class DOES have some code included in the book, specifically it starts on page 126. Before we delve into the code there, let's create our file by adding a new class to the navigation folder and naming it 'SiteMapsHandler.vb' &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;. Following the code in the book starting at the bottom of page 126, we want to make sure that our class implements the iHttpHandler interface (requiring import of System.Web). When you press enter, you'll get stubs for two required elements (IsReusable property and ProcessRequest Method).&lt;/p&gt;  &lt;p&gt;The IsReusable property can just return true &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;. ProcessRequest has a few more lines, but only a couple. You can find them at the top of page 127. As we start, your class should look like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Imports System.Web      &lt;br /&gt;      &lt;br /&gt;Public Class SiteMapHandler       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Implements IHttpHandler&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public ReadOnly Property IsReusable() As Boolean Implements _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Web.IHttpHandler.IsReusable       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return True       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Property&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Implements System.Web.IHttpHandler.ProcessRequest&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BaseContext = context       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CreateSiteMap()       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Response.Flush()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Response.End()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Sub       &lt;br /&gt;      &lt;br /&gt;End Class&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You'll notice that about every line gives us an error since nearly everything in this method is undefined. Examining the downloaded file, we find that these undefined items are actually properties created in our class (with the exception of CreateSiteMap()) &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;. Add the following properties to your class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Dim _baseContext As HttpContext      &lt;br /&gt;Public Property BaseContext() As HttpContext       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _baseContext       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As HttpContext)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _baseContext = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property       &lt;br /&gt;      &lt;br /&gt;Public ReadOnly Property Response() As HttpResponse       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return BaseContext.Response       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property       &lt;br /&gt;      &lt;br /&gt;Public ReadOnly Property Request() As HttpRequest       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return BaseContext.Request       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This will take care of all but our CreateSiteMap() method error. So without further ado we'll add our CreateSiteMap method. This can be found on page 128. (Note: if you haven't used XDocument to do XML before, it is very particular about where you put your %&amp;gt; characters so follow the below code exactly so that you don't get errors - I learned by hard experience since I hadn't used it before). Add the following for your CreateSiteMap method:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Sub CreateSiteMap()      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Response.ContentType = &amp;quot;application/xml&amp;quot;&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim lSiteMapNodes As List(Of SiteMapInfo)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Using siteMaprpt As New SiteMapRepository       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMapNodes = siteMaprpt.GetSiteMapNodes       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Using&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim xSiteMap As XDocument = &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;urlset xmlns=&amp;quot;http://www.sitemaps.org/schemas/sitemap/0.9&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;%= From lSiteMapNode In lSiteMapNodes.AsEnumerable _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Select &amp;lt;url&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;loc&amp;gt;&amp;lt;%= lSiteMapNode.URL %&amp;gt;&amp;lt;/loc&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;lastmod&amp;gt;&amp;lt;%= lSiteMapNode.DateUpdated %&amp;gt;&amp;lt;/lastmod&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;changefreq&amp;gt;weekly&amp;lt;/changefreq&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;priority&amp;gt;0&amp;lt;/priority&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/url&amp;gt; %&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/urlset&amp;gt;&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Response.Write(xSiteMap.ToString())       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now we also need to add our handler to the web.config so that our website knows to use it. Add the following to the httpHandlers section of your web.config:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;add verb=&amp;quot;GET&amp;quot; path=&amp;quot;sitemap.xml&amp;quot; validate=&amp;quot;false&amp;quot; type=&amp;quot;TBH.SiteMapHandler, TBHBLL, Version=3.5.0.1, Culture=neutral, PublickeyToken=null&amp;quot; /&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p class="MySubHeadings"&gt;A URL Rewrite Class &lt;/p&gt;  &lt;p&gt;This I feel is one of the less complete modules in the chapter. Originally when I attempted to create the code from this chapter I was only creating code that I found in the solution section. This meant that a couple critical pieces of this module were left out. By looking through the chapter, there was actually much more available.&lt;/p&gt;  &lt;p&gt;First we'll need to create a class for our Rewrite code. This should go in a folder called 'Module' in our BLL. Once the folder is created, add a class file and name it URLRewrite.vb. &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We get our first code pieces starting on page 124 in the book. Right off, we should make sure that our class implements the IHttpModule interface, so add that to your class definition. Next, we can the code we need for the Init method. We can add that and you class should look something like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Class URLRewrite      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Implements IHttpModule       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Sub Init(ByVal context As System.Web.HttpApplication) _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Implements System.Web.IHttpModule.Init       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AddHandler context.BeginRequest, AddressOf BeginRequest       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Sub       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; Public Sub Dispose() Implements System.Web.IHttpModule.Dispose       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; End Sub       &lt;br /&gt;      &lt;br /&gt;End Class&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You'll notice that while the book says we should intercept the AuthorizeRequest event that we're using the BeginRequest event. There is a difference between what we see on page 124 and what we read later on pages 135-6, but I went with the one that matched the code download, BeginRequest. &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Next, skip over to page 135 and we'll start adding the rest of the module. We will create a variable to use for Regular Expressions. Add the following to your class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Shared wwwRegex As New Regex(&amp;quot;https?://www\.&amp;quot;, RegexOptions.IgnoreCase Or RegexOptions.Compiled)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Following along on page 136, we'll also add the BeginRequest event handler that we registered in our Init method. This is defined as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Sub BeginRequest(ByVal sender As Object, ByVal e As EventArgs)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim app As HttpApplication = CType(sender, HttpApplication)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim Request As HttpRequest = app.Request       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim Response As HttpResponse = app.Response&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim sRequestedURL As String = Request.Url.ToString.ToLower       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim redirectURL As String = String.Empty       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim bWWW As Boolean = wwwRegex.IsMatch(sRequestedURL)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If bWWW Then redirectURL = wwwRegex.Replace(sRequestedURL, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; String.Format(&amp;quot;{0}://&amp;quot;, Request.Url.Scheme))       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; Rewrite(app)       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The Rewrite method is next, it is found on page 137 towards the bottom. Unfortunately there is a SIGNIFICANT difference between the code in the book and the code in the downloaded version. The book talks about doing a 301 redirect and looking up the information in the sitemap table, however the book doesn't seem to implement this. The downloaded code seems to to this, so I will be including that code rather than just the book's code. &lt;strong&gt;*Gap-Filled*&lt;/strong&gt; To start, let's create a helper function for our Rewrite method. Add the following to your code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Sub Do301Redirect(ByVal response As HttpResponse, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal redirectURL As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; response.RedirectLocation = redirectURL       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; response.StatusCode = 301       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; response.End()       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now let's create our Rewrite method. Add the following:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Sub Rewrite(ByVal app As HttpApplication)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If app.Context.Request.Path.ToLower.EndsWith(&amp;quot;.aspx&amp;quot;) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Using lSiteMapRst As New SiteMapRepository_       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (Globals.Settings.DefaultConnectionStringName)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim lURLFile As String = _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Helpers.GetURLPath(app.Context.Request.Url.ToString)&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim lSiteMap As SiteMapInfo = lSiteMapRst.GetSiteMapInfoByURL _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (lURLFile.Replace(Globals.Settings.devSiteName, &amp;quot;&amp;quot;))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If Not IsNothing(lSiteMap) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If lSiteMap.RealURL &amp;lt;&amp;gt; lURLFile Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HttpContext.Current.RewritePath(&amp;quot;/&amp;quot; &amp;amp; lSiteMap.RealURL, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; False)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ElseIf lSiteMap.URL &amp;lt;&amp;gt; lSiteMap.RealURL Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Do301Redirect(app.Response, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Path.Combine(Globals.Settings.SiteDomainName, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lSiteMap.URL))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Using       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I did make one change from the downloaded code, I removed a settings variable since all we did was get our Globals.Settings object and it wasn't that much more work to add the Globals path to the beginning of the settings object when it was called.&lt;/p&gt;  &lt;p&gt;You'll also notice that we created an error with our Helpers.GetURLPath that we haven't defined yet. We'll go define that now so that we can successfully build our application.&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;Another Method for our Helpers Class&lt;/p&gt;  &lt;p&gt;I haven't found where much of the Helper class is defined in the book, so I went to the code download for this method. &lt;strong&gt;*Gap-Filled*&lt;/strong&gt; Go over to your Helpers class and we'll add the following method:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Shared Function GetURLPath(ByVal sUrl As String) As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim _Regex As Regex = New Regex(&amp;quot;://[^/]+/(?&amp;lt;path&amp;gt;[^?\s&amp;lt;&amp;gt;#&amp;quot;&amp;quot;]+)&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If _Regex.Matches(sUrl).Count &amp;gt; 0 Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _Regex.Match(sUrl).Groups(1).ToString()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return sUrl       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p class="MySubHeadings"&gt;Configuring the ELMAH Error Logging Add-In&lt;/p&gt;  &lt;p&gt;One of my little pet peeves is when you download something and then have to search all over the internet for specific instructions on how to install and configure it. This was the case for some information for getting ELMAH started in our project. I think I'm going to have to pull from a couple articles, as well as using the book, to get it all 100% happy. &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Starting on page 139, it talks about configuring ELMAH, so we can get some of our direction from the book, however before we do that, we'll need to get it installed. I found &lt;a href="http://www.itscodingtime.com/itscodingtime/post/Adding-ELMAH-to-your-ASPNET-Web-Site.aspx" target="_blank"&gt;a short article&lt;/a&gt; that I based my installation on, basically you:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://code.google.com/p/elmah/" target="_blank"&gt;Download ELMAH&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;Extract the Files. &lt;/li&gt;    &lt;li&gt;Copy the Elmah.dll into the BIN directory of your website. &lt;/li&gt;    &lt;li&gt;Configure ELMAH in your web.config. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;We can now go to the book and do a little bit of configuration. First we need to add a Section definition to our web.config, much like we needed to do for our BeerHouseSection for configuration. Add the following to the ConfigSections element of your web.config:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;sectionGroup name=&amp;quot;elmah&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;section name=&amp;quot;security&amp;quot; requirePermission=&amp;quot;false&amp;quot; type=&amp;quot;Elmah.SecuritySectionHandler, Elmah&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;section name=&amp;quot;errorLog&amp;quot; requirePermission=&amp;quot;false&amp;quot; type=&amp;quot;Elmah.ErrorLogSectionHandler, Elmah&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;section name=&amp;quot;errorMail&amp;quot; requirePermission=&amp;quot;false&amp;quot; type=&amp;quot;Elmah.ErrorMailSectionHandler, Elmah&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;section name=&amp;quot;errorFilter&amp;quot; requirePermission=&amp;quot;false&amp;quot; type=&amp;quot;Elmah.ErrorFilterSectionHandler, Elmah&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;lt;/sectionGroup&amp;gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now we can add the configuration information into an Elmah section in our web.config. Add the following to the Configuration section in your web.config.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;elmah&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;security allowRemoteAccess=&amp;quot;0&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;errorLog type=&amp;quot;Elmah.SqlErrorLog, Elmah&amp;quot; connectionStringName=&amp;quot;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;errorFilter&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;test&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;equal binding=&amp;quot;HttpStatusCode&amp;quot; value=&amp;quot;404&amp;quot; &lt;strike&gt;value&lt;/strike&gt;Type=&amp;quot;Int32&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/test&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/errorFilter&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;errorMail from=&amp;quot;error@thebeerhouse.com&amp;quot; to=dogbert@dogbert.com subject=&amp;quot;Exception in the Beerhouse Site.&amp;quot; async=&amp;quot;true&amp;quot; smptPort=&amp;quot;25&amp;quot; smtpServer=&amp;quot;mail.thebeerhouse.com&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;lt;/elmah&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You'll notice that I have made a correction in the 'equal' element. The book has incorrectly listed this attribute as valueType &lt;strong&gt;*Gap-Filled*&lt;/strong&gt;, the correct attribute is type. Finally for configuration we need to add handlers so that the modules will actually be used. We need to add the following to our system.web section within the HttpModules subsection:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;add name=&amp;quot;ErrorLog&amp;quot; type=&amp;quot;Elmah.ErrorLogModule, Elmah&amp;quot; /&amp;gt;      &lt;br /&gt;&amp;lt;add name=&amp;quot;ErrorMail&amp;quot; type=&amp;quot;Elmah.ErrorMailModule, Elmah&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;lt;add name=&amp;quot;ErrorFilter&amp;quot; type=&amp;quot;Elmah.ErrorFilterModule, Elmah&amp;quot; /&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and the following into our system.web's httpHandlers section:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;add verb=&amp;quot;POST,GET,HEAD&amp;quot; path=&amp;quot;elmah.axd&amp;quot; type=&amp;quot;Elmah.ErrorLogPageFactory, Elmah&amp;quot; /&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Finally, one last piece that I had a harder time finding, and that is setting up the database. To do this, you need to add the ELMAH table and it's 3 stored procedures (thanks &lt;a href="http://blog.ninethsense.com/elmah-integration-to-aspnet-in-simple-steps/" target="_blank"&gt;NinethSense&lt;/a&gt;). If you downloaded the ELMAH packages, there is a folder in the zip file labeled 'DB'. In this folder, you will find the script to setup your DB. I chose to use SQL server so I loaded the SQLServer.sql file into my SQL Server Management Studio and ran the script. Viola the DB is setup.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Epilogue &lt;/p&gt;  &lt;p&gt;Well, there you go, hopefully you'll find this helpful, I certainly would have.&lt;/p&gt;  &lt;p&gt;Having finished with this particular chapter, I have started reading further (albeit in pieces here and there) in chapter 5 and I think that actually everything will be much easier to understand in these chapters. If they aren't, then look forward to another post in the series...?&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx&amp;amp;;subject=Filling+in+the+Gaps+-+Problem+Design+Solution+3.5+-+Part+2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx&amp;amp;;title=Filling+in+the+Gaps+-+Problem+Design+Solution+3.5+-+Part+2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx&amp;amp;title=Filling+in+the+Gaps+-+Problem+Design+Solution+3.5+-+Part+2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx&amp;amp;;title=Filling+in+the+Gaps+-+Problem+Design+Solution+3.5+-+Part+2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx&amp;amp;;title=Filling+in+the+Gaps+-+Problem+Design+Solution+3.5+-+Part+2&amp;amp;;top=1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2010/03/19/Filling-in-the-Gaps-_2D00_-Problem-Design-Solution-3.5-_2D00_-Part-2.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://aspadvice.com/aggbug.aspx?PostID=61586" width="1" height="1"&gt;</description><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/Asp.net/default.aspx">Asp.net</category></item><item><title>Using the WinForm ComboBox Like the Asp.Net DropDownList</title><link>http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx</link><pubDate>Tue, 13 Oct 2009 00:27:25 GMT</pubDate><guid isPermaLink="false">e709ad4c-0c15-48eb-915e-c462c6e85445:56703</guid><dc:creator>Yougotiger</dc:creator><slash:comments>0</slash:comments><comments>http://aspadvice.com/blogs/net_discoveries/comments/56703.aspx</comments><wfw:commentRss>http://aspadvice.com/blogs/net_discoveries/commentrss.aspx?PostID=56703</wfw:commentRss><wfw:comment>http://aspadvice.com/blogs/net_discoveries/rsscomments.aspx?PostID=56703</wfw:comment><description>&lt;p class="MyHeadings"&gt;Prologue&lt;/p&gt;  &lt;p&gt;Most of the development I do centers around ASP.Net rather than WinForms. I do however do a little work in the WinForms sphere occasionally. I was putting something together the other day and found that there are some little, yet significant differences between the WinForms ComboBox and the ASP.Net DropDownList. Specifically I found that in the ASP.Net DropDownList, you can set the displayed text to be different than the value. The WinForms ComboBox doesn't allow this.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Problem&lt;/p&gt;  &lt;p&gt;In the application I was developing, I wanted the ComboBox to behave like the ASP DropDownList and allowing me to display text yet have the VALUE returned be an integer that corresponded with another array. WinForms DOES support this, HOWEVER, not in as straight forward a way as you might think. (In the interest of giving credit where credit is due, I pieced together much of this post by reading &lt;a href="http://www.mgbrown.com/PermaLink37.aspx" target="_blank"&gt;a post and subsequent comments&lt;/a&gt; on Martin G. Brown's blog - Thanks for the help Martin).&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Solution&lt;/p&gt;  &lt;p&gt;First, a little about the difference between ASP and WinForms ComboBoxes. Take the example here of an ASP.Net DropDownList's front-end code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;asp:DropDownList runat=&amp;quot;server&amp;quot; ID=&amp;quot;ddlTest&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:ListItem Text=&amp;quot;My Name&amp;quot; Value=&amp;quot;0&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:ListItem Text=&amp;quot;Your Name&amp;quot; Value=&amp;quot;1&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;lt;/asp:DropDownList&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;or the following back-end code for adding items to an existing DropDownList:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;ddlTest.Items.Add(New ListItem(&amp;quot;My Name&amp;quot;, 0))      &lt;br /&gt;ddlTest.Items.Add(New ListItem(&amp;quot;Your Name&amp;quot;, 1)) &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In either case, notice that I can explicitly set the value and the text to be different. This allows me to display friendly text, yet pass around a key (such as an ID) when the user selects the entry rather than having to use the text as a key. Also notice that I can set both of these at the same time. This would allow me to pull a list of objects, say names from a database, and then display them along with associated values (such as a primary key id) pretty quickly. Let's look at doing this with the WinForms combo box.&lt;/p&gt;  &lt;p&gt;Let's do a little setup here so we can continue with our project when we're done &amp;quot;looking.&amp;quot; Create a Windows Form application and add a ComboBox (name it cmboDoIt) and two Buttons (one named btnDoIt and one named btnShowIt).&lt;/p&gt;  &lt;p&gt;Click on the ComboBox, go to the properties pane and click the ... button next to Items, you'll notice that the String Collection Editor comes up. It asks you to enter the strings for the collection, one per line. So you can enter the text, but not the values. Let's try doing it runtime and see if that'll do it.&lt;/p&gt;  &lt;p&gt;If you go to the code behind and try adding an item, like you did for the DropDownList. Notice that the Item that you add is of type Object. But of what kind of object? String. This doesn't allow you to add a value to the item. So how could we do this? The answer lies in the ability of a ComboBox to be bound to a data source. If we create a data source with more than one &amp;quot;column&amp;quot;, we can bind to the data source and then SPECIFY which column will be the text and which will be the value.&lt;/p&gt;  &lt;p&gt;To do this, we first need to create a data source. We'll do this by creating a class to hold our two data pieces. Add the following class definition to our form, just before the final End Class tag:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Class ValueDescriptionPair      &lt;br /&gt;&amp;#160;&amp;#160; Private _value As Object       &lt;br /&gt;&amp;#160;&amp;#160; Private _description As String       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; Public Sub New(ByVal Description As String, ByVal Value As Object)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _value = Value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _description = Description       &lt;br /&gt;&amp;#160;&amp;#160; End Sub       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; Public ReadOnly Property Value() As Object       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160; End Property       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; Public ReadOnly Property Description() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _description       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160; End Property       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; Public Overrides Function ToString() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _description       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Function       &lt;br /&gt;End Class&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Basically we create a class that can hold both our value and our description. We add a ToString function so that we don't end up with any funky output when we use our description. We also define a constructor so we can pass our value/description pair in to create the object. Now we can create an array of our ValueDescriptionPair objects, load it with data (we'll just do it by hand in this example) and then bind it all to our ComboBox. To do this, add the following to our btnDoIt_Click event handler.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Dim vdpArray As New ArrayList      &lt;br /&gt;      &lt;br /&gt;vdpArray.Add(New ValueDescriptionPair(&amp;quot;My Name&amp;quot;, 0))       &lt;br /&gt;vdpArray.Add(New ValueDescriptionPair(&amp;quot;Your Name&amp;quot;, 1))       &lt;br /&gt;cmboDoIt.DataSource = vdpArray       &lt;br /&gt;cmboDoIt.ValueMember = &amp;quot;Value&amp;quot;       &lt;br /&gt;cmboDoIt.DisplayMember = &amp;quot;Description&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Here we create an ArrayList of our ValueDescriptionPair. We then add 2 elements, bind our DataSource and then define which member to assign as a value and which to assign as a description. Let's wire up one last piece before we run the application. Add the following to your btnShowIt_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;MessageBox.Show(&amp;quot;The value for &amp;quot; &amp;amp; cmboDoIt.SelectedItem.ToString &amp;amp; _      &lt;br /&gt;&amp;#160;&amp;#160; &amp;quot; is &amp;quot; &amp;amp; cmboDoIt.SelectedValue)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This will just display your selected entry and the corresponding value. Now to use the value, all you need to do is use the ComboBox's SelectedValue property and you're good to go.&lt;/p&gt;  &lt;p&gt;Note: as an FYI, this can also be done using a generic collection. Simply change the following lines (remember to add the Imports System.Collections.Generic statement to the top of the code as well):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&lt;strike&gt;Dim vdpArray As New ArrayList        &lt;br /&gt;&lt;/strike&gt;Dim vdpArray As New List(Of ValueDescriptionPair)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p class="MyHeadings"&gt;Epilogue &lt;/p&gt;  &lt;p&gt;There you have it. Pretty simple once you've got it all in place, but very convenient when needed. I'm not sure why you can't add data items that contain both value and description like you can with the DropDownList but it's an easy work around.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx&amp;amp;;subject=Using+the+WinForm+ComboBox+Like+the+Asp.Net+DropDownList" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx&amp;amp;;title=Using+the+WinForm+ComboBox+Like+the+Asp.Net+DropDownList" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx&amp;amp;title=Using+the+WinForm+ComboBox+Like+the+Asp.Net+DropDownList" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx&amp;amp;;title=Using+the+WinForm+ComboBox+Like+the+Asp.Net+DropDownList" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx&amp;amp;;title=Using+the+WinForm+ComboBox+Like+the+Asp.Net+DropDownList&amp;amp;;top=1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/10/12/Using-the-WinForm-ComboBox-Like-the-Asp.Net-DropDownList.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://aspadvice.com/aggbug.aspx?PostID=56703" width="1" height="1"&gt;</description><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/Customizing+Controls/default.aspx">Customizing Controls</category><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/Windows+Forms/default.aspx">Windows Forms</category><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/DataBinding/default.aspx">DataBinding</category><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/ComboBox/default.aspx">ComboBox</category></item><item><title>Using the AJAX Control Toolkit’s CollapsiblePanel in a GridView</title><link>http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx</link><pubDate>Tue, 07 Jul 2009 23:19:41 GMT</pubDate><guid isPermaLink="false">e709ad4c-0c15-48eb-915e-c462c6e85445:54897</guid><dc:creator>Yougotiger</dc:creator><slash:comments>1</slash:comments><comments>http://aspadvice.com/blogs/net_discoveries/comments/54897.aspx</comments><wfw:commentRss>http://aspadvice.com/blogs/net_discoveries/commentrss.aspx?PostID=54897</wfw:commentRss><wfw:comment>http://aspadvice.com/blogs/net_discoveries/rsscomments.aspx?PostID=54897</wfw:comment><description>&lt;p class="MyHeadings"&gt;Prologue&lt;/p&gt;  &lt;p&gt;On our company website, the one I mention so frequently (or is it infrequently as often as I post&amp;#8230;), we have a data display prominently mounted where it can be viewed by people who are not employees. If they visit our facility, they can view the data (in a GridView) that shows basic information they want to know. The information that feeds the dataset has quite a bit more information that may actually be helpful to various departments within the company, but we don't want to display it to non-employees. What I&amp;#8217;d like to do is retain the same GridView but reveal more data when someone in the company clicks the row. Basically, I want to have every other row hidden and then reveal an associated, hidden row when the non hidden row is clicked. (FYI - I also have code I don't talk about in this post that disables this functionality for people who are not inside the company).&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Problem&lt;/p&gt;  &lt;p&gt;A possible solution that I found was the &lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CollapsiblePanel/CollapsiblePanel.aspx" target="_blank"&gt;CollapsiblePanel&lt;/a&gt; control that is part of the &lt;a href="http://www.asp.net/ajax/ajaxcontroltoolkit/" target="_blank"&gt;AJAX Control Toolkit&lt;/a&gt;. This provides functionality to do pretty much what I was looking to do. The question is trying to integrate it with a GridView. In my searching on the Internet, I didn&amp;#8217;t find much that would suffice for what I wanted to do. One of the closest I found was a kind of an &lt;a href="http://mosesofegypt.net/post/GridView-Grouping-Master-Detail-Drill-Down-Using-jQuery-AJAX.aspx" target="_blank"&gt;integrated master/detail&lt;/a&gt; that I found on a blog. I chose to go ahead and try to use the CollapsiblePanel control. The problem that I found is that you can&amp;#8217;t alternate data in a GridView, the row is the row and nothing else. In other words, I found I couldn&amp;#8217;t do the 2 things I wanted to with the row 1. hide it (every other row should be hidden), and 2. put different data in it automatically (i.e. different data in every other row, one with public info, one with private). I did get it working, but it's not a wonderfully clean solution, not quite like I expected. Let&amp;#8217;s examine how I did it.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Solution&lt;/p&gt;  &lt;p&gt;To get started we need to create a new page and add to it a GridView control, it also needs a little configuration so, add the following markup code to your front-end code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;cc1:ToolkitScriptManager ID=&amp;quot;ToolkitScriptManager1&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;      &lt;br /&gt;&amp;lt;/cc1:ToolkitScriptManager&amp;gt;       &lt;br /&gt;&amp;lt;asp:gridview ID=&amp;quot;gvwTest&amp;quot; runat=&amp;quot;server&amp;quot; AutoGenerateColumns=&amp;quot;true&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AllowSorting=&amp;quot;True&amp;quot;&amp;gt;       &lt;br /&gt;&amp;lt;/asp:gridview&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We've just created a very basic GridView, nothing much to look at. We also added a ScriptManager for our CollapsPanelExtender to use later. Next we'll create a data source to populate the GridView. Add the following to your Page_Load event:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;gvwTest.DataSource = CreateDataSource()      &lt;br /&gt;gvwTest.DataBind()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And then we'll add a helper function CreateDataSource to our application so that it will create and populate the data source,&amp;#160; add the following function:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Function CreateDataSource() As DataTable      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim dt As New DataTable()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dt.Columns.Add(New DataColumn(&amp;quot;FirstName&amp;quot;, GetType(String)))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dt.Columns.Add(New DataColumn(&amp;quot;LastName&amp;quot;, GetType(String)))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dt.Columns.Add(New DataColumn(&amp;quot;City&amp;quot;, GetType(String)))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dt.Columns.Add(New DataColumn(&amp;quot;State&amp;quot;, GetType(String)))       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim dr As DataRow       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dr = dt.NewRow()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dr(&amp;quot;FirstName&amp;quot;) = &amp;quot;Sally&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dr(&amp;quot;LastName&amp;quot;) = &amp;quot;Smith&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dr(&amp;quot;City&amp;quot;) = &amp;quot;Phoenix&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dr(&amp;quot;State&amp;quot;) = &amp;quot;Arizona&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dt.Rows.Add(dr)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dr = dt.NewRow()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dr(&amp;quot;FirstName&amp;quot;) = &amp;quot;John&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dr(&amp;quot;LastName&amp;quot;) = &amp;quot;Doe&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dr(&amp;quot;City&amp;quot;) = &amp;quot;Seattle&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dr(&amp;quot;State&amp;quot;) = &amp;quot;Washington&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dt.Rows.Add(dr)       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return dt       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This function creates a DataTable and then adds 4 columns, 2 for the name and 2 for their location. Next, we create 2 rows and populate the data. Finally, we return the DataTable.&lt;/p&gt;  &lt;p&gt;Now we're ready to get started. If you run your project, you'll see that we have 2 rows each with 4 columns. Let's say though that you'd rather have the location be on the next row and have it revealed only when you click on the name. How do we get 1/2 of one row to display as the 1st row and the 2nd half of the SAME row to display as the 2nd row? The answer is that you can't. If we want to create something custom like that, we need to create a custom TemplateField and this will have to be laid out by hand, I chose to do it by table.&lt;/p&gt;  &lt;p&gt;So let's customize our GridView. We'll add support for the collapse panel at the same time. Let's start with how we want to lay it out. We want one row with the full name. We don't want the location to show until the name is clicked, and then we want it to &amp;quot;fly-out&amp;quot; (or down) and reveal the location. What we'll end up with is a table with two rows, one row with name one with location. This table will be nested in EACH row of our GridView. Let's get started by creating a header for our GridView. Add the following between our GridView tags:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;Columns&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TemplateField&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;HeaderTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/HeaderTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TemplateField&amp;gt;       &lt;br /&gt;&amp;lt;/Columns&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We'll be using one actual GridView field, typically each field (in our data) would map to a cell in the row, but we're going to use one cell per GridView row to display our data. Within our HeaderTemplate we'll add a table labeling the data that will be displayed. Add the following inside your HeaderTemplate:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;asp:Table runat=&amp;quot;server&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;First Name&amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;Last Name&amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;lt;/asp:Table&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That sets the header for the GridView, now for our row. We need to add two tables, one for each &amp;quot;row&amp;quot; we want to present (one for name, one for location). We'll also surround our tables each with a panel so we can target them with the CollapsePanelExtender. All this will be added to our ItemTemplate, add the following just below our HeaderTemplate:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;ItemTemplate&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlTitle&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Table runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Image ID=&amp;quot;imgToggle&amp;quot; ImageUrl=&amp;quot;expand.jpg&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:label ID=&amp;quot;lblFirstName&amp;quot; Text='&amp;lt;%#Eval(&amp;quot;FirstName&amp;quot;)%&amp;gt;' runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblLastName&amp;quot; Text='&amp;lt;%#Eval(&amp;quot;LastName&amp;quot;)%&amp;gt;' runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Table&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Panel&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlLocation&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Table runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblCity&amp;quot; Text='&amp;lt;%#Eval(&amp;quot;City&amp;quot;)%&amp;gt;' runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblState&amp;quot; Text='&amp;lt;%#Eval(&amp;quot;State&amp;quot;)%&amp;gt;' runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Table&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Panel&amp;gt;       &lt;br /&gt;&amp;lt;/ItemTemplate&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You'll notice that I reference an image called 'expand.jpg' this is a little &amp;quot;expander&amp;quot; arrow. The CollapsePanelExtender will actually toggle this image with a 'collapse.jpg' that we'll define later. You can grab any expander and collapser image you like and just direct our code to it (I'm using the ones from the toolkit's sample project). If you run your project, you'll see that our first column has our tables in it and our other columns still appear. We can turn those off by changing our AutoGenerateColumns to false. If you run it again, we should have our tables and no extraneous columns.&lt;/p&gt;  &lt;p&gt;Now that we've got everything in place, we just need to get our CollapsPanelExtender working.&lt;/p&gt;  &lt;p&gt;We'll need a CollapsePanelExtender for each row that we'll be targeting so we should add the extender inside our ItemTemplate and put it directly after our last panel tag. We'll start with just the basics and add a couple things in a minute. Add the following just below your last panel tag:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;cc1:CollapsiblePanelExtender ID=&amp;quot;cpeDetails&amp;quot;      &lt;br /&gt;runat=&amp;quot;server&amp;quot;       &lt;br /&gt;TargetControlID=&amp;quot;pnlLocation&amp;quot;       &lt;br /&gt;CollapseControlID=&amp;quot;pnlTitle&amp;quot;       &lt;br /&gt;ExpandControlID=&amp;quot;pnlTitle&amp;quot;       &lt;br /&gt;Enabled=&amp;quot;true&amp;quot; &amp;gt;       &lt;br /&gt;&amp;lt;/cc1:CollapsiblePanelExtender&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now if you run your project, we'll have our two &amp;quot;rows&amp;quot; and if you click on the name row, the location row will shrink and if you click it again, it will reveal. Lets modify a couple settings to make it a little better. First let's add functionality for the expander image so it changes automatically, add the following attributes to your cpeDetails extender:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;ImageControlID=&amp;quot;imgToggle&amp;quot;      &lt;br /&gt;CollapsedImage=&amp;quot;Collapse.jpg&amp;quot;       &lt;br /&gt;ExpandedImage=&amp;quot;expand.jpg&amp;quot;       &lt;br /&gt;Collapsed=&amp;quot;true&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This will set the CollapsPanelExtender to do image swapping and make will make the location panels collapsed by default. One other change to make would to alternate colors for the rows, add the following attribute to your GridView control:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;AlternatingRowStyle-BackColor=&amp;quot;Silver&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Run it again, and see that it works, we have one &amp;quot;row&amp;quot; with the name and another &amp;quot;row&amp;quot; with the location that can be revealed by clicking on the name.Notice that each row can be expanded and contracted separately from the other rows and that everything is in working order with the collapse and expand images. There we go, a working 'Collapsible' table from a GridView.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Epilogue &lt;/p&gt;  &lt;p&gt;You'll notice that I said earlier, this isn't a really clean way to do things, I'll stand by that. The header doesn't necessarily match up with our data, and we're limited on what we can do about that. You can set some cell widths and cell alignments in our tables so that they move where they should be, but you only have so much control over a table, it might expand to fit contents and stuff like that.&lt;/p&gt;  &lt;p&gt;However, it is a cheap and easy way to display some extra information pretty easily, and it does look reasonably good in our production environment.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx&amp;amp;;subject=Using+the+AJAX+Control+Toolkit%e2%80%99s+CollapsiblePanel+in+a+GridView" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx&amp;amp;;title=Using+the+AJAX+Control+Toolkit%e2%80%99s+CollapsiblePanel+in+a+GridView" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx&amp;amp;title=Using+the+AJAX+Control+Toolkit%e2%80%99s+CollapsiblePanel+in+a+GridView" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx&amp;amp;;title=Using+the+AJAX+Control+Toolkit%e2%80%99s+CollapsiblePanel+in+a+GridView" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx&amp;amp;;title=Using+the+AJAX+Control+Toolkit%e2%80%99s+CollapsiblePanel+in+a+GridView&amp;amp;;top=1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/07/07/Using-the-AJAX-Control-Toolkit_1920_s-CollapsiblePanel-in-a-GridView.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://aspadvice.com/aggbug.aspx?PostID=54897" width="1" height="1"&gt;</description><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/Asp.net/default.aspx">Asp.net</category><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/GridView/default.aspx">GridView</category></item><item><title>A Provider by Any Other Name…Doesn’t Smell So Sweet</title><link>http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx</link><pubDate>Tue, 16 Jun 2009 17:42:56 GMT</pubDate><guid isPermaLink="false">e709ad4c-0c15-48eb-915e-c462c6e85445:53981</guid><dc:creator>Yougotiger</dc:creator><slash:comments>0</slash:comments><comments>http://aspadvice.com/blogs/net_discoveries/comments/53981.aspx</comments><wfw:commentRss>http://aspadvice.com/blogs/net_discoveries/commentrss.aspx?PostID=53981</wfw:commentRss><wfw:comment>http://aspadvice.com/blogs/net_discoveries/rsscomments.aspx?PostID=53981</wfw:comment><description>&lt;p class="MyHeadings"&gt;Prologue&lt;/p&gt;  &lt;p&gt;A funny thing happened on the way to the… management page. I found a kind of an anomaly taking place when you configure your Membership Provider use one application and your Role Provider is configured to use a different one. What I found is that I had users I deleted still assigned to some of my roles (phantom users).&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Problem&lt;/p&gt;  &lt;p&gt;In the process of creating ‘&lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/09/29/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-1.aspx" target="_blank"&gt;A Better ASP.Net User/Role Management Page’&lt;/a&gt; found that I (without realizing it) had set the application name for my Roles Provider to be different than the one for the Membership Provider. This leads to some interesting side effects that I didn’t expect. Since I haven’t found any posts regarding this on the internet, I thought I’d touch on the subject mostly as an interesting side note so people can see what’s going on, not that we solve any problems per se but we’ll be informed at least by the time we’re done.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Solution&lt;/p&gt;  &lt;p&gt;Before we can get started, we’ll need to make sure we have a website setup with a Membership and a Role provider configured. We should be able to piggyback off the SQLExpress Membership Provider website that was created in the &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx" target="_blank"&gt;last post&lt;/a&gt;. We’ll want to follow the post and create a Membership provider that we can configure. We’ll scrap all the front end and back-end code from the project except the web.config. We’ll also need to define a Role provider while we’re at it so after you add your Membership provider information, add the following as a Role provider right below it:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;roleManager enabled=&amp;quot;true&amp;quot; defaultProvider=&amp;quot;myCustomRoleProvider&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;providers&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;add name=&amp;quot;myApp&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connectionStringName=&amp;quot;mySqlServer&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; type=&amp;quot;System.Web.Security.SqlRoleProvider, System.Web,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Version=2.0.0.0, Culture=neutral,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PublicKeyToken=b03f5f7f11d50a3a&amp;quot;/&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/providers&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/roleManager&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;As a side note, make both your membership and roles provider’s &lt;strong&gt;applicationName=”myApp”&lt;/strong&gt;, so that we start with our providers using the same application. Along the same lines of the project we’re piggybacking on, this will allow us to customize our role provider using the ASPNETDB database that was provided to us. Next we’ll want to create a front end that will allow us to show the results we’re creating as we go, so we know what’s happening.&lt;/p&gt;  &lt;p&gt;Open a blank default.aspx (or create it if it doesn’t already exist) and add the following to the front-end code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;div&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Roles by User:&amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblRolesByUser&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Users by Role:&amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblUsersByRole&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Label&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This give us two labels to populate, one we’ll populate with our users and show what roles they are assigned to, and the other we’ll populate with the roles and the users that are assigned to them. Now for the back-end code. Add the following helper functions to the code behind:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Function GetRolesByUser() As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim sb As New StringBuilder()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; For Each member As MembershipUser In Membership.GetAllUsers()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; sb.Append(&amp;quot;&amp;lt;strong&amp;gt;&amp;quot; &amp;amp; member.UserName &amp;amp; &amp;quot;&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For Each role As String In Roles.GetRolesForUser(member.UserName)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; sb.Append(&amp;quot;-&amp;quot; &amp;amp; role &amp;amp; &amp;quot;&amp;lt;br&amp;gt;&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Next       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return sb.ToString()       &lt;br /&gt;End Function       &lt;br /&gt;      &lt;br /&gt;Private Function GetUsersByRole() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim sb As New StringBuilder()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; For Each role As String In Roles.GetAllRoles()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; sb.Append(&amp;quot;&amp;lt;strong&amp;gt;&amp;quot; &amp;amp; role &amp;amp; &amp;quot;&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For Each member As String In Roles.GetUsersInRole(role)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; sb.Append(&amp;quot;-&amp;quot; &amp;amp; member &amp;amp; &amp;quot;&amp;lt;br&amp;gt;&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Next       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return sb.ToString()       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;These functions do exactly what we were talking about before. Once cycles through the members in the database, retrieves the roles they are assigned to and then displays this list. The other cycles through the roles and makes a list of each role and all the members assigned to it then displays it. To run the functions, add the following to your Page_Load event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;lblRolesByUser.Text = GetRolesByUser()      &lt;br /&gt;lblUsersByRole.Text = GetUsersByRole()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This will populate the labels we have on the page using our two helper functions as soon as the page is run. Now were’ ready to do some playing around. Let’s make sure that to start, you have your membership and roles providers both using the same application name. This way we can see how things SHOULD behave. Add the following line to both your membership and your role provider:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;applicationName=&amp;quot;myApp&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p class="MySubHeadings"&gt;For First My First Trick – or – Meet the Phantom User&lt;/p&gt;  &lt;p&gt;Now let’s go add some users and roles and make some assignments. If you open the solution explorer panel and click ‘ASP.Net Configuration’ button, we’ll get the ‘ASP.net Web Site Administration Tool’ (WSAT – well call it) webpage. Let’s add 2 users and 2 roles and then assign 1 user to each role. For my purposes, I’ll use:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;     &lt;table cellspacing="0" cellpadding="2"&gt;         &lt;tr&gt;           &lt;td&gt;&lt;strong&gt;&lt;u&gt;Users&lt;/u&gt;&lt;/strong&gt;&lt;/td&gt;            &lt;td&gt;&lt;strong&gt;&lt;u&gt;Roles&lt;/u&gt;&lt;/strong&gt;&lt;/td&gt;         &lt;/tr&gt;          &lt;tr&gt;           &lt;td&gt;MajorPain&lt;/td&gt;            &lt;td&gt;BigManOnCampus&lt;/td&gt;         &lt;/tr&gt;          &lt;tr&gt;           &lt;td&gt;JunkMeister&lt;/td&gt;            &lt;td&gt;LittleLoser&lt;/td&gt;         &lt;/tr&gt;       &lt;/table&gt;   &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and just assign roles directly across a row. Once we have our users and roles setup, we can run our application and we should get a listing that looks like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;&lt;strong&gt;JunkMeister&lt;/strong&gt;       &lt;br /&gt;-LittleLoser       &lt;br /&gt;&lt;strong&gt;MajorPain&lt;/strong&gt;       &lt;br /&gt;-BigManOnCampus       &lt;br /&gt;      &lt;br /&gt;Users by Role:       &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;       &lt;br /&gt;-MajorPain       &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;       &lt;br /&gt;-JunkMeister&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You can see that we have our 2 users, 2 roles and 2 assignments (each user is assigned to one role). All this is displayed to us two different ways. Now delete one of your users (I got rid of MajorPain) and refresh the page. Your results should look something like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;&lt;strong&gt;JunkMeister&lt;/strong&gt;       &lt;br /&gt;-LittleLoser       &lt;br /&gt;      &lt;br /&gt;Users by Role:       &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;       &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;       &lt;br /&gt;-JunkMeister&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Notice that we have our 1 user, and that the user we deleted was removed from the roles list as well, we have 1 user, 2 roles, and only 1 user assigned. This is what we would expect to see. If we remove a user, the provider code should remove its entry from all the roles assignments.&lt;/p&gt;  &lt;p&gt;Now let’s get a little fancy with things and see what happens. First, let’s change the name of the membership provider. In your Web.config, change the membership provider’s applicationName to be something different:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;applicationName=&amp;quot;myOtherApp&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now refresh your page and see what gets listed. It should look something like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;      &lt;br /&gt;Users by Role:       &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;       &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;       &lt;br /&gt;-JunkMeister&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We have 0 users and 2 roles, but we do have 1 user assigned to our role… Wait a minute, how can we have a user assigned to our LitteLoser role if we don’t have any users? We’ll answer that in a minute. For now, let’s look at it the other way around, change our membership’s applicationName back to “myApp” and change the Roles provider’s applicationName to “MyOtherApp”. Refresh your page and see that it should come up like this&amp;quot;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;&lt;strong&gt;JunkMeister        &lt;br /&gt;&lt;/strong&gt;      &lt;br /&gt;Users by Role:&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Notice that we have our user back, but we don’t have any roles in our application AND that since there aren’t any roles in our application, our user isn’t assigned to any… It seems there a bit of a disconnect? We get roles with a phantom user assigned, but not any phantom roles assigned for our user. Interesting, No?&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;A Good Magician Never Reveals – or – I am Not a Good Magician&lt;/p&gt;  &lt;p&gt;Ok, let’s dig into what’s happening and see how it all works, change your membership and role’s applicationName back to myApp and setup with your 2 users, 2 roles and 2 assignments again. If you’ve got it setup right, your page should display as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;&lt;strong&gt;JunkMeister&lt;/strong&gt;       &lt;br /&gt;-LittleLoser       &lt;br /&gt;&lt;strong&gt;MajorPain&lt;/strong&gt;       &lt;br /&gt;-BigManOnCampus       &lt;br /&gt;      &lt;br /&gt;Users by Role:       &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;       &lt;br /&gt;-MajorPain       &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;       &lt;br /&gt;-JunkMeister&lt;img style="display:inline;margin:0px 5px;" src="http://aspadvice.com/photos/images_to_go_with_what_ive_learned/images/53848/original.aspx" align="right" /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now, let’s dig into the behind the scenes. Open your ‘Server Explorer’ panel. Open your database, then the tables node and let’s look into our tables. First, right-click your Users table and select ‘Show table data’. You should see 2 users, like the picture to the right. &lt;img style="display:inline;margin:5px;" src="http://aspadvice.com/photos/images_to_go_with_what_ive_learned/images/53849/original.aspx" align="right" /&gt;&lt;/p&gt;  &lt;p&gt;Let’s also dig into the Roles table, show the table data for the roles, and you should see a table with 2 roles, again nothing surprising (see image at right). &lt;/p&gt;  &lt;p&gt;Ok, let’s look at one more table, show &lt;img style="display:inline;margin:5px;" src="http://aspadvice.com/photos/images_to_go_with_what_ive_learned/images/53850/original.aspx" align="right" /&gt;the table data for your UsersInRoles table. You should see two assignments (two rows). While the IDs may look intimidating, we can see from our pictures above that the UserID comes from the Users table and the RoleID comes form the Roles table. Thus we can translate our IDs and see that we have our 2 users, 2 roles and 2 assignments.&lt;/p&gt;  &lt;p&gt;Now, let’s repeat our previous experiment, but let’s start with the Role provider. Change your Role Provider’s applicationName and refresh our browser, we should get:&lt;/p&gt;  &lt;p&gt;Roles by User:    &lt;br /&gt;&lt;strong&gt;JunkMeister&lt;/strong&gt;     &lt;br /&gt;&lt;strong&gt;MajorPain      &lt;br /&gt;&lt;/strong&gt;    &lt;br /&gt;Users by Role:&lt;/p&gt;  &lt;p&gt;&lt;img style="display:inline;margin:0px 5px;" src="http://aspadvice.com/photos/images_to_go_with_what_ive_learned/images/53851/original.aspx" align="right" /&gt; 2 users, 0 Roles and 0 role assignments, as it should be. Where did our roles go? For that we need to open one more table, show table data on our Applications table. This should show our ApplicationID’s notice how we have two applications, now notice that our roles and our users both have an applicationID as well. Both These all have an applicationID that matches our ‘myApp’ application. Meaning that when we change our Roles provider to to be ‘myOtherApp’, it no longer detects that we have any roles or role assignments since it looks for roles and role assignments only with our applicationID (Note: not strictly correct as we’ll see shortly). This allows you to use the same database for more than one website, each website just needs a different applicationID and the data resides in the same database.&lt;/p&gt;  &lt;p&gt;Now let’s try it with our Membership Provider, change the Roles Provider’s applicationName back to ‘myApp’ and our Membership Provider’s applicationName to ‘myOtherApp’. Now refresh our page and see what happens. If it works like when we changed our Roles provider, we we would expect to end up with 2 Roles, 0 users, and 0 role assignments, as all the users assigned to roles exist in ‘myApp’ and we’ve ask for users in ‘myOtherApp’. Refresh your page and you should get:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;      &lt;br /&gt;Users by Role:       &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;       &lt;br /&gt;-MajorPain       &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;       &lt;br /&gt;-JunkMeister&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We should be expecting 0 users, 2 roles and 0 assignments, but Notice that we’re getting usernames that we SHOUDN’T be getting: 0 users, 2 roles and 2 assignments. What gives? Check out our code behind. In our ‘GetUsersByRole’ function, we’re getting all our roles, iterating through them and using the role to pull all members in the role by using the Roles.GetUsersInRole(role) method. For some reason, this built-in function has some kind of glitch where it doesn’t filter out users that aren’t in our specified application (myOtherApp). That’s the secret of the trick: we should be getting only users returned to us who are IN our specified application (myOtherApp), but in fact we’re getting back users that &lt;strong&gt;WE SHOULD NOT BE ABLE TO SEE&lt;/strong&gt; by virtue of our configuration.&lt;/p&gt;  &lt;p&gt;&lt;img style="display:inline;margin:5px;" src="http://aspadvice.com/photos/images_to_go_with_what_ive_learned/images/53850/original.aspx" align="right" /&gt;We can see part of the root of the problem by looking at our UsersInRoles table. Notice something missing? Yeah, it’s got no applicationID. When we use the Roles.GetUsersInRole, it should process the UserID against the applicationID (from a different table) and do a filter. It doesn’t.&lt;/p&gt;  &lt;p&gt;To confirm that we’re getting roles assignments (and thus usernames) from multiple applications, right now add another user (MickyMouse) and assign him to the ‘BigManOnCampus’ role and refresh your page. You should see something like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;&lt;strong&gt;MickyMouse&lt;/strong&gt;       &lt;br /&gt;-BigManOnCampus       &lt;br /&gt;Users by Role:       &lt;br /&gt;      &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;       &lt;br /&gt;-MajorPain       &lt;br /&gt;-MickyMouse       &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;       &lt;br /&gt;-JunkMeister&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We only have 1 user in our users list, but we have a total of 3 users to roles assignments AND we’ve pulled usernames from &lt;strong&gt;TWO DIFFERENT APPLICATIONS AT THE SAME TIME &lt;/strong&gt;and used them!&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;I Think You Underestimate My Trickiness – or – Different appNames From the Get Go&lt;/p&gt;  &lt;p&gt;Ok, now let’s get a little more hairy with it. While we’re here, delete your MickeyMouse user. and then refresh your page. Since we’re in the application where we created our MickyMouse user, the user should be deleted and removed from all roles, right? Refresh and see, you should see something like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;      &lt;br /&gt;Users by Role:       &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;       &lt;br /&gt;-MajorPain       &lt;br /&gt;-MickyMouse       &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;       &lt;br /&gt;-JunkMeister&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We’ve got 0 users, but 3 users assigned to roles. Technically, we’re pulling two of the users from a different application, so they DO exist in the database, but our MickeyMouse user no longer exists in the Database or he would show up in the user section (he’s not being filtered out, we’re in his application). What gives?&lt;/p&gt;  &lt;p&gt;We’re finally getting down to the crux of the problem I originally found. I had accidentally created an applicationID for each the Role and the Membership, and didn’t even notice till I pulled the data we are here that little things were being left floating around (like our MickeyMouse assignment).&lt;/p&gt;  &lt;p&gt;Let’s see if we can create the issue from the ground up and watch what’s happening in our database so we can see &lt;u&gt;how&lt;/u&gt; it happens. Rather than going through the interface of the WSAT, I’ll have you delete directly from the tables since we won’t be able to 100% flush our users out otherwise (since MickyMouse doesn’t exist yet still shows up).&lt;/p&gt;  &lt;p&gt;If you select all your rows in VS.Net, while ‘showing table data’, you can press delete and delete all the rows. Let’s do this for the following tables and &lt;u&gt;in this order&lt;/u&gt; (no cheating, no looking at the data in the tables, now):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;UsersInRole      &lt;br /&gt;Roles       &lt;br /&gt;Membership       &lt;br /&gt;Users&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The order of tables here will give a little bit of hint of things to come, (hint: we haven’t mentioned the membership table at all, have we). Also, in preparation for our next excercise we want to make sure that our Membership and Roles providers have DIFFERENT applicationNames. Ok, now if you run your page again, you should end up with a blank list:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;      &lt;br /&gt;Users by Role:&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is to be expected since we don’t have any users or roles in our database. So, now that we have everything setup, let’s add 2 users and 2 roles, but NOT make any assignments just yet. Open your WSAT and add back in our MajorPain and JunkMeister users and add back in our BigManOnCampus and LittleLoser roles. Refresh your page and you should see:&lt;/p&gt;  &lt;p&gt;Roles by User:    &lt;br /&gt;&lt;strong&gt;JunkMeister&lt;/strong&gt;     &lt;br /&gt;&lt;strong&gt;MajorPain      &lt;br /&gt;&lt;/strong&gt;    &lt;br /&gt;Users by Role:     &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;     &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="display:inline;margin:0px 5px;" src="http://aspadvice.com/photos/images_to_go_with_what_ive_learned/images/53874/original.aspx" align="right" /&gt;2 users, 2 roles and 0 assignments – as expected. First, let’s look into our tables. Let’s start with UsersInRoles. Notice we get nothing (no assignments yet). Now, let’s check our Roles and Users tables. You shouldn’t be surprised to see that each has 2 entries, and also shouldn’t be surprised that the roles have a &lt;u&gt;different&lt;/u&gt; ApplicationID than the users do.&lt;/p&gt;  &lt;p&gt;Ok, now let’s add a users to a role. Start with MajorPain, add him to the BMOC role and then refresh our page. We should see our assignment:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;&lt;strong&gt;JunkMeister&lt;/strong&gt;       &lt;br /&gt;&lt;strong&gt;MajorPain&lt;/strong&gt;       &lt;br /&gt;-BigManOnCampus       &lt;br /&gt;      &lt;br /&gt;Users by Role:       &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;       &lt;br /&gt;-MajorPain       &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now let’s look back at our UsersInRole table and see what it looks like. Much like we’d expect, one row showing our one assignment. Now, let’s go back and look at our &lt;strong&gt;users&lt;/strong&gt; table.     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="display:block;float:none;margin-left:auto;margin-right:auto;" src="http://aspadvice.com/photos/images_to_go_with_what_ive_learned/images/53875/original.aspx" /&gt; &lt;/p&gt;  &lt;p&gt;WHOA. Where did the extra MajorPain come from? Well, since we didn’t have a MajorPain in our Role’s Application, the database creates one in our users table and assigns it the ApplicationID for our Roles provider. Notice that we have two MajorPains, but they do have 2 different ApplicationIDs assigned to them (one for our membership provider’s application and one for our role provider’s application).&lt;/p&gt;  &lt;p&gt;Now, observe what happens when we delete our user MajorPain. Go ahead and delete him. What happened? Right, only one disappeared. Notice it was the one associated with our Membership provider. Our Roles provider’s MajorPain user is still intact. Refresh our page and see what happens.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;&lt;strong&gt;JunkMeister        &lt;br /&gt;&lt;/strong&gt;      &lt;br /&gt;Users by Role:       &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;       &lt;br /&gt;-MajorPain       &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We have no MajorPain user, but we have a phantom MajorPain in our role assignments list. Thus we created a 2nd MajorPain user and now we’ve &lt;u&gt;stranded him&lt;/u&gt; in our database. And we can’t just change our membership provider to match his applicationID and delete him. Change your Membership provider’s ApplicationName to match your Roles Provider and refresh your page. Theoretically, he should show up as a user right? WRONG! When you refresh, you get:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Roles by User:      &lt;br /&gt;      &lt;br /&gt;Users by Role:       &lt;br /&gt;&lt;strong&gt;BigManOnCampus&lt;/strong&gt;       &lt;br /&gt;-MajorPain       &lt;br /&gt;&lt;strong&gt;LittleLoser&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;No users, but we do get our phantom user to role assignment. What gives? Go back to our Membership table and take a look. We only have one row in this table, it belongs to JunkMeister (match is UserID up with the User’s table). But if you go to the User’s table and look you’ll see our phantom MajorPain user. Try to lookup &lt;u&gt;our phantom MajorPain’s UserID, it isn’t in the Membership table&lt;/u&gt;. Unless the user has an entry in this table (Membership), it won’t show up when we use our membership methods. Even removing our ‘phantom’ user from the role doesn’t remove our phantom user from the Users table.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Epilogue &lt;/p&gt;  &lt;p&gt;So there it is, phantom users in our membership/roles database.&lt;/p&gt;  &lt;p&gt;Funny, I started out this post with the intent to create an innocently intentioned post about something strange that I found. However as I worked my way through presenting it, I found I was kind of disillusioned with the innocence. While I’m generally pretty happy with Microsoft and their related .Net technologies, it seems that this would be considered a fairly LARGE security loophole and/or could cause problems for any one of a number of reasons:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;By changing the role provider’s application name, I can (if they exist) retrieve usernames that belong to a &lt;u&gt;different&lt;/u&gt; application. While it might be assumed that I wouldn’t be able to access more than one application without proper permission, this seems somewhat lacking in security. (Especially when you consider some of the functionality that wasn’t baked into the providers for security’s sake – such as changing a username – it seems that this wasn’t a deliberate oversight). &lt;/li&gt;    &lt;li&gt;Along with the above problem, I can, by changing the role provider’s application name, pull username/role assignments from MULTIPLE applications AT ONE TIME. Again, this seems like somewhat of a security problem – and I’ll get INCORRECT data that may give me hiccups in my code. &lt;/li&gt;    &lt;li&gt;I can retrieve usernames and role associations that &lt;u&gt;no longer exist&lt;/u&gt;. This poses a problem if I want to process things using information from the roles list. I &lt;u&gt;may not be able&lt;/u&gt; to manipulate things based on the Roles.GetUsersInRoles() method, because it returns INCORRECT data and may thus return some unexpected exceptions. &lt;/li&gt;    &lt;li&gt;We can create phantom users in our users table, however, we CANNOT, through the providers mechanisms provided by Microsoft, purge the phantom user(s) entirely from the database. &lt;/li&gt;    &lt;li&gt;And on top of it all, I wasn’t able to find ANY documentation anywhere regarding the issue. Maybe nobody else is dumb enough to split their providers (like I was), but it seems like if it was designed to behave this way, that it would be explained somewhere in documentation or at least on a blog somewhere. At least tell us it’s possible, but warn us that it’s &lt;strike&gt;stupid&lt;/strike&gt; a bad idea. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Anyhow, as I see it “Lucy, you got some splainin’ to do!” – or – At the very least, we should be very careful to make sure that we don’t mix up our applicatioNames when we are configuring our providers, or we may get some unexpected and undesirable results.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx&amp;amp;;subject=A+Provider+by+Any+Other+Name%e2%80%a6Doesn%e2%80%99t+Smell+So+Sweet" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx&amp;amp;;title=A+Provider+by+Any+Other+Name%e2%80%a6Doesn%e2%80%99t+Smell+So+Sweet" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx&amp;amp;title=A+Provider+by+Any+Other+Name%e2%80%a6Doesn%e2%80%99t+Smell+So+Sweet" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx&amp;amp;;title=A+Provider+by+Any+Other+Name%e2%80%a6Doesn%e2%80%99t+Smell+So+Sweet" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx&amp;amp;;title=A+Provider+by+Any+Other+Name%e2%80%a6Doesn%e2%80%99t+Smell+So+Sweet&amp;amp;;top=1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/06/16/A-Provider-by-Any-Other-Name_2620_Doesn_1920_t-Smell-So-Sweet.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://aspadvice.com/aggbug.aspx?PostID=53981" width="1" height="1"&gt;</description><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/Asp.net/default.aspx">Asp.net</category><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/Roles/default.aspx">Roles</category><category domain="http://aspadvice.com/blogs/net_discoveries/archive/tags/Membership/default.aspx">Membership</category></item><item><title>Configuring Your SQLExpress Membership Provider</title><link>http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx</link><pubDate>Thu, 02 Apr 2009 19:24:46 GMT</pubDate><guid isPermaLink="false">e709ad4c-0c15-48eb-915e-c462c6e85445:51932</guid><dc:creator>Yougotiger</dc:creator><slash:comments>5</slash:comments><comments>http://aspadvice.com/blogs/net_discoveries/comments/51932.aspx</comments><wfw:commentRss>http://aspadvice.com/blogs/net_discoveries/commentrss.aspx?PostID=51932</wfw:commentRss><wfw:comment>http://aspadvice.com/blogs/net_discoveries/rsscomments.aspx?PostID=51932</wfw:comment><description>&lt;p class="MyHeadings"&gt;Prologue&lt;/p&gt;  &lt;p&gt;In the process of writing the last series of posts to create ‘A Better ASP.Net Member/Role Management Page’ (here’s a link to the &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/09/29/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-1.aspx" target="_blank"&gt;1st part&lt;/a&gt;), I used a SQL Express database located in my App_data folder. This was the first time I’ve used one. I have access to a full blown external SQL Server for development (since that’s what I’ll be doing in production). Due to my lack of experience with this form of database, I had a heck of time figuring out how to configure my membership provider. In &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/11/06/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-4.aspx" target="_blank"&gt;part 4&lt;/a&gt; of the series, I looked at enabling/disabling some functionality of the page based on how the Membership provider was configured. Obviously, to check that the functionality of the page is working correctly, I needed to change the configuration of the provider. Therein lied the problem.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Problem&lt;/p&gt;  &lt;p&gt;When I created my database in the App_Data folder for this project, VS.Net 2008 did a lot of the work for me. While this isn’t bad, what I found is that I had a dickens of time figuring out how to get my Membership provider configured to use something besides the default settings. So I thought I’d create an entry on how to do it since I had a tough time with it.&lt;/p&gt;  &lt;p&gt;We’ll start from the very beginning (i.e. from scratch) for this post, but the basic problem is that when VS.Net does all the work, the web.config does NOT contain any membership provider configuration information, so it isn’t readily apparent how to change the provider’s configuration. Once we figure out what’s going on and how to rectify it, it actually becomes pretty easy though. (Note, giving credit where credit is due, I got a lot of information from &lt;a href="http://www.asp.net/Learn/Security/tutorial-04-vb.aspx" target="_blank"&gt;this site&lt;/a&gt;, but have pared it down to the very basics).&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Solution&lt;/p&gt;  &lt;p&gt;First off, let’s start with a new website. We only need one page in the site, it comes with a default.aspx and we’ll just use that. We’ll begin by setting up the page to display a couple things. Add the following to your front-end code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;div&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; Configuration: &amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;asp:TextBox ID=&amp;quot;txtCurrentConfig&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TextMode=&amp;quot;MultiLine&amp;quot; Width=&amp;quot;400&amp;quot; Height=&amp;quot;200&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160; Members:&amp;lt;br /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;asp:GridView ID=&amp;quot;gvMembers&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;/asp:GridView&amp;gt;       &lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We’re creating a TextBox to hold some configuration information that we’ll retrieve in our back-end, and then a GridView that we’ll use to pull members from the database. This will help us to see if we’ve done something horribly wrong ;-).&lt;/p&gt;  &lt;p&gt;We’ll need also to create our database before we can pull any membership from it. Right-click your App_Data folder and select ‘Add New Item…’ From this list, you want to select SQL Server Database. Name it ‘aspnetdb.mdf’ and click ‘Add’. Now we should have a database file in our App_Data folder. If you go to the Server Explorer panel, you can open the database, you’ll notice that it doesn’t have ANY tables in it, including the membership and roles tables that we want to be able to access. We need to add these.&lt;/p&gt;  &lt;p&gt;Adding the membership and roles information basically amounts to running the aspnet_regsql.exe against our database and the the functionality will be added to the database. The article I referenced above has a great walkthrough on this, however I found that if I ran the aspnet_regsql tool in GUI mode, somehow the SQL service on my machine didn’t have rights to access the DB file (as it was in my My Documents folder under the VS 2008 folder, and somehow the GUI – despite being run under my account – couldn’t see my profile). Also, I couldn’t get my SQL Server to attach to the file for the same reason. What I did find that worked though, was &lt;a href="http://weblogs.asp.net/lhunt/archive/2005/09/26/425966.aspx" target="_blank"&gt;an article&lt;/a&gt; that detailed how to run aspnet_regsql by command line (hey, and the article’s got a classy color scheme too ;-) ). This is how I’ll do our database. Open a command prompt and run the following:&lt;/p&gt;  &lt;p&gt;aspnet_regsql -A all -C &amp;quot;Data Source=.\SQLEXPRESS;Integrated Security=True;User Instance=True&amp;quot; -d &amp;quot;C:\&lt;strong&gt;&amp;lt;Filepath&amp;gt;&lt;/strong&gt;\APP_DATA\aspnetdb.mdf&amp;quot;&lt;/p&gt;  &lt;p&gt;You should notice that if you have the filepath to your database file correct, it will add a few a few different things to your database and then report it is finished. If you refresh your database in the Server Explorer, you’ll see that now we have some tables (and stored procedures). We’re ready to do some stuff with our membership provider now.&lt;/p&gt;  &lt;p&gt;Next, we’ll add a user to our database so that we can do some testing using our GridView. We’ll do it the easy way, open the Website Administration Tool by clicking the button on the toolbar in your Solution explorer. Once the page comes up, Click the ‘Security’ link. Click the link to ‘Select Authentication Type’, and we’ll set it to forms authentication. Select ‘From the internet’ and click ‘Done’. Also, we’ll click the link to ‘Enable Roles’. Now, let’s add a user to our database, click the ‘Create User’ link. On the next screen, let’s create a user, just to prove a point, use ‘password’ for the password. When you click ‘Create User’. You’ll notice that the user creation fails because we don’t have a non-alphanumeric character in the password. Go ahead and create a new password that meets the criteria and then create the user.&lt;/p&gt;  &lt;p&gt;Ok, now we’ll add some back-end code so we can see what’s happening with our provider. Add the following to your page_load event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;gvMembers.DataSource = Membership.GetAllUsers()      &lt;br /&gt;gvMembers.DataBind()       &lt;br /&gt;      &lt;br /&gt;txtCurrentConfig.Text = &amp;quot;Password format:&amp;quot; &amp;amp; Membership.Provider.PasswordFormat &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;What we’re doing is retrieving all our members, and binding them to the GridView. We also pull the PasswordFormat specified for the membership provider and display that in our textbox. If you run your page, you’ll see that we successfully pull our lone member into the GridView, and that our PasswordFormat is 1. This PasswordFormat correlates with the enumeration for PasswordFormats that is defined in the .Net Framework as follows (ok, I’m interpreting what they’ve done but it still stands):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Enum MembershipPasswordFormat      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Clear = 0       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Encrypted = 2       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Hashed = 1       &lt;br /&gt;End Enum&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You can see that the 1 indicates that we have Hashed passwords. Herein lies our dilemma (yes, we’re finally to it). Let’s say we wanted to use Encrypted passwords instead? (I needed to change this so I could test the different PasswordFormats against the code in the aforementioned post). Normally, we’d just go and change the Membership provider’s details in the web.config. So let’s go do it. Go look in your web.config for the membership provider’s definition… go on, I’ll wait. Haven’t found it? Keep looking. While you’re at it, see if you can find the connectionString for the membership database… Can’t find it either? There must be one, otherwise how would it connect to the database? You’re right, we’ve mysteriously created a provider we don’t know how to configure.&lt;/p&gt;  &lt;p&gt;The solution lies in this: our Machine.config has a default membership provider defined. When we created our membership stuff, this default provider is used by… default. We have to override this if we want to customize it. So how do we do this? First, let’s open our machine.config and see if we can find our Membership provider’s definition there. The machine.config can be found at C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config (assuming you’re %system% folder is Windows). Search down and you’ll find that there is in fact a provider defined here:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;membership&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;providers&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;add name=&amp;quot;AspNetSqlMembershipProvider&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; type=&amp;quot;System.Web.Security.SqlMembershipProvider, System.Web,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Version=2.0.0.0, Culture=neutral,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PublicKeyToken=b03f5f7f11d50a3a&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connectionStringName=&amp;quot;LocalSqlServer&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; enablePasswordRetrieval=&amp;quot;false&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; enablePasswordReset=&amp;quot;true&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; requiresQuestionAndAnswer=&amp;quot;true&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; applicationName=&amp;quot;/&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; requiresUniqueEmail=&amp;quot;false&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; passwordFormat=&amp;quot;Hashed&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; maxInvalidPasswordAttempts=&amp;quot;5&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; minRequiredPasswordLength=&amp;quot;7&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; minRequiredNonalphanumericCharacters=&amp;quot;1&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; passwordAttemptWindow=&amp;quot;10&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; passwordStrengthRegularExpression=&amp;quot;&amp;quot;/&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/providers&amp;gt;       &lt;br /&gt;&amp;lt;/membership&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;There it is. The current definition of our membership provider. So how do we override it? Simple, we need to define a new one in our web.config code. Somewhere inside your system.web section of the web.config, add a membership provider section and define a new provider as such:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;membership&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;providers&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;add name=&amp;quot;myCustomProvider&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; type=&amp;quot;System.Web.Security.SqlMembershipProvider, System.Web,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Version=2.0.0.0, Culture=neutral,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PublicKeyToken=b03f5f7f11d50a3a&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; passwordFormat=&amp;quot;Encrypted&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connectionStringName=&amp;quot;LocalSqlServer&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;/providers&amp;gt;       &lt;br /&gt;&amp;lt;/membership&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Notice that we changed our passwordFormat to be Encrypted (so when we run the application, our format should now show as 2. How do we know what connectionStringName to use? We’ll, for one we could just use the same string as the one defined in the provider in the machine.config, but we can also look through the machine.config and see that we have a connectionString defined there too.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;connectionStrings&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;add name=&amp;quot;LocalSqlServer&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connectionString=&amp;quot;data source=.\SQLEXPRESS;Integrated       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Instance=true&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; providerName=&amp;quot;System.Data.SqlClient&amp;quot;/&amp;gt;       &lt;br /&gt;&amp;lt;/connectionStrings&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You’ll see, that the default connectionString setup in the machine.config is ‘LocalSqlServer’. We could redefine it, but this will work just fine for us. So run your application and see what we get. The member binds fine to the GridView, but we’re still showing that our password is hashed (1). What’s the deal? Well, what’s happening, is we’re still using the default provider in the machine.config. We need to specify that we want to use ours instead. to do this, modify your membership element opening tag with the following attribute addition:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;membership defaultProvider=&amp;quot;myCustomProvider&amp;quot;&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Here we define that OUR provider should be the default provider. We also can take an additional step recommended my many people on the internet, and that is to remove the default provider from the machine.config. To do that, you can just add the clear element before your &amp;lt;add&amp;gt; provider element as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;providers&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;clear/&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;add name=”…..&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Alternatively, we could also remove the provider specifically by using the following in place of the &amp;lt;clear/&amp;gt; element:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;remove name=&amp;quot;AspNetSqlMembershipProvider&amp;quot; /&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We’re simply telling .Net in to remove the default provider (named AspNetSqlMembershipProvider). Now run your application again. Notice that our passwordFormat is now 2 – Encrypted. BUT, also notice that we no longer are successfully binding our GridView to the member we created. What gives? Add the following line to the end of your page_load event handler and we’ll see:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;txtCurrentConfig.Text &amp;amp;= vbCrLf &amp;amp; &amp;quot;Application Name:&amp;quot; &amp;amp; _      &lt;br /&gt;&amp;#160;&amp;#160; Membership.Provider.ApplicationName&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now run your application again. Notice that the applicationName is the name of your website. If you look in your machine.config, what is the applicationName being used? Right, “/” or root. Effectively, by leaving out the applicationName in our membership provider definition, we’ve changed to a different application. Our user is assigned to the root application, and we’re pulling members from a different application (our website name). To fix that, just add the following to your provider’s definition:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;applicationName=&amp;quot;/&amp;quot; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Run your application again, and you’ll see that now we have our member back. Or better yet, we could create a unique application name for our application and start creating users in that instead. This helps to ensure that our users are unique to our application and not being reused from some other application that used the root application name.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Epilogue &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a title="http://weblogs.asp.net/lhunt/archive/2005/09/26/425966.aspx" href="http://weblogs.asp.net/lhunt/archive/2005/09/26/425966.aspx"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Well, there it is. Now you can configure your SQLExpress membership provider as you desire. There are a load of other settings that we didn’t define in ours (as witnessed by the settings in the machine.config) and defining them is easy as adding the settings.&lt;/p&gt;  &lt;p&gt;Funny how something so simple could cause me so much searching all over the internet looking for the solution. Honestly, it took me quite a long time to find the answer, I probably wasted 2 hours or more before I stumbled into the answer. Maybe I’m just dense, it and it should be common knowledge, but it wasn’t to me.&lt;/p&gt;  &lt;p&gt;Anyhow, it’s there, and if either of us ever need it, we’ll know where to look for the answer.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx&amp;amp;;subject=Configuring+Your+SQLExpress+Membership+Provider" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx&amp;amp;;title=Configuring+Your+SQLExpress+Membership+Provider" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx&amp;amp;title=Configuring+Your+SQLExpress+Membership+Provider" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx&amp;amp;;title=Configuring+Your+SQLExpress+Membership+Provider" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx&amp;amp;;title=Configuring+Your+SQLExpress+Membership+Provider&amp;amp;;top=1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/04/02/Configuring-Your-SQLExpress-Membership-Provider.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://aspadvice.com/aggbug.aspx?PostID=51932" width="1" height="1"&gt;</description></item><item><title>A Better ASP.Net Member/Role Management Page Pt. 7</title><link>http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx</link><pubDate>Mon, 30 Mar 2009 22:13:29 GMT</pubDate><guid isPermaLink="false">e709ad4c-0c15-48eb-915e-c462c6e85445:51872</guid><dc:creator>Yougotiger</dc:creator><slash:comments>4</slash:comments><comments>http://aspadvice.com/blogs/net_discoveries/comments/51872.aspx</comments><wfw:commentRss>http://aspadvice.com/blogs/net_discoveries/commentrss.aspx?PostID=51872</wfw:commentRss><wfw:comment>http://aspadvice.com/blogs/net_discoveries/rsscomments.aspx?PostID=51872</wfw:comment><description>&lt;p class="MyHeadings"&gt;Prologue&lt;/p&gt;  &lt;p&gt;**Author Note – If you are bewildered by a line (perhaps two) that are red and bold, don’t they that they’re errors, they are corrections/additions. Please see the comments, after the article for comments regarding the highlighted line(s).**&lt;/p&gt;  &lt;p&gt;In previous posts, we created “A better ASP.Net Member/Role Management Page”. If you want to follow along, you can create the management page yourself by reviewing all the posts for &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/09/29/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-1.aspx"&gt;part 1&lt;/a&gt;, &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/10/07/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-2.aspx"&gt;part 2&lt;/a&gt;, &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/10/14/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-3.aspx"&gt;part 3&lt;/a&gt;, &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/11/06/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-4.aspx"&gt;part 4&lt;/a&gt;, &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx"&gt;part 5&lt;/a&gt; and &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx"&gt;part 6&lt;/a&gt;. In this post, I plan on ‘tying up some loose ends,’ by adding some things that I’d like to have in the management page, but that were over and above basic functionality. Most of this is stuff that I thought of adding while I was creating the page originally, but didn’t want to add yet, or that I didn’t have time to research at the time. Now's my chance to do it.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Problem&lt;/p&gt;  &lt;p&gt;Time to add some ‘fluffy stuff’ and add some stuff that will make it just that little bit better… (and I found now that I’ve written this post, add some corrections as well…)&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Solution&lt;/p&gt;  &lt;p&gt;To get started, let's make it easier to customize the look and feel of the user control.&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;CssClass Properties&lt;/p&gt;  &lt;p&gt;The first thing we’ll look at adding will give you a little more flexibility as far as styling your control. Currently it should look pretty decent but, it looks like Microsoft’s theme, and not our site (I don’t know about yours, but ours doesn’t look like Microsoft’s). I’m sure that we’ll change our site again someday, so it doesn’t make sense to hard code the styles and not have the option to change the styles on the fly. Lucky for us it should be reasonably easy to build in this functionality. I won’t cover how to do every one of them, but if we do it right we should be able to cover a bunch in a couple of groups, and the basics of how it can be done should give you a significant start.&lt;/p&gt;  &lt;p&gt;Creating our own styles for the page doesn’t mean we have to remove the styling that we’ve done so far. We’ll just give the user the ability to override our styles to fit their needs. I’ve compiled a list of all the places that I would like to give the user the ability to define the CssClass (I think I got them all, I may have missed some…). We’ll start with the easy ones and show how it’s done and then let you loose on the others. First off, we’ve got three groups of classes that we can set the whole group all at once, our TextBoxWaterMarkExtenders watermark class, our ModalPopupExtender’s background class (the cover for the existing page) and our Panels that will be our modal dialogs (the actual panels being modally displayed). Each of these groups can each be set at once since they’ll be the same (all the watermarks will be the same for instance). Let’s start with our TextBoxWaterMarkExtenders. Here’s the list of controls I compiled:&lt;/p&gt;  &lt;p&gt;tweSearchUsersFor    &lt;br /&gt;tweSearchUsersForRoles     &lt;br /&gt;tweSecurityAnswer (note, this may be misspelled in other posts as tbeSec…)     &lt;br /&gt;tweNewUsername (note, this may be misspelled in other posts as tbeNew…)     &lt;br /&gt;tweNewRoleName&lt;/p&gt;  &lt;p&gt;What we’ll do is create a property for the WaterMarkTextCssClass and then set all their WaterMarkCssClasses when the property is set. Add the following to your back-end code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private _TextBoxWatermarkCssClass As String      &lt;br /&gt;Public Property TextBoxWatermarkCssClass() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _TextBoxWatermarkCssClass       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _TextBoxWatermarkCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; tweSearchUsersFor.WatermarkCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; tweSearchUsersForRoles.WatermarkCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; tweSecurityAnswer.WatermarkCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; tweNewUsername.WatermarkCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; tweNewRoleName.WatermarkCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I cheated, I use the Refactor! tool, that I’ve mentioned &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2006/11/15/Cool-Tool-_2D00_-Refactor_2100_.aspx"&gt;before&lt;/a&gt;, so all I had to do to create the property is write the declaration line and then right click on it and select and refactor. I then added all the TextBoxWaterMarkExtender controls from the list to the set portion of the property and assigned the value passed in to their WatermarkCssClass property. Now go to our test page that tests our user control and in the HTML markup that uses the control, add an attribute for WatermarkCssClass and assign it a css class with different style than the one we’re using (my css class had one line: color: red;). Run it and you’ll see that it overrides the one that we assigned in the control’s front end markup. (Note, I’ve found that when you add properties this way, you may need to close and reopen the page that’s using the control otherwise it may not show our new property as an intellisense available attribute).&lt;/p&gt;  &lt;p&gt;One other small note: if you notice I saved the property to a global variable. Realistically, we could just put the value to the controls and then call it good, but if we want to pull it and look at later, it then it might be nice to pull it from a central point rather than from one of the controls.&lt;/p&gt;  &lt;p&gt;Next, we’ll do the ModalPopupExtender BackgroundCssClass. The ModalPopupExtenders that I cataloged are:&lt;/p&gt;  &lt;p&gt;mpeCreateUser    &lt;br /&gt;mpeMessageDialog     &lt;br /&gt;mpeDeleteUserConfirm     &lt;br /&gt;mpeEditUser     &lt;br /&gt;mpeChangePassword     &lt;br /&gt;mpeConfirmResetPassword     &lt;br /&gt;mpeChangeSecurityQuestion     &lt;br /&gt;mpeChangeUsername     &lt;br /&gt;mpeDeleteRoleConfirm     &lt;br /&gt;mpeChangeRoleName     &lt;br /&gt;mpeRoleRenameConfirm&lt;/p&gt;  &lt;p&gt;To create their property, add the following to your back-end code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private _ModalPopupBackgroundCssClass As String      &lt;br /&gt;Public Property ModalPopupBackgroundCssClass() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _ModalPopupBackgroundCssClass       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _ModalPopupBackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeCreateUser.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeMessageDialog.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeDeleteUserConfirm.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeEditUser.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeChangePassword.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeConfirmResetPassword.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeChangeSecurityQuestion.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeChangeUsername.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeDeleteRoleConfirm.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeChangeRoleName.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mpeRoleRenameConfirm.BackgroundCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Nothing much different than we did before, just more controls to assign to. Again, add an attribute to your control declaration on the test page and see the difference if you run it (my popup background is orange now :-0 ). Finally for the easy ones, let’s do the panels that will be displayed as the ModalPopup. The list I compiled are:&lt;/p&gt;  &lt;p&gt;pnlMessageDialog    &lt;br /&gt;pnlDeleteUserConfirm     &lt;br /&gt;pnlCreateUser     &lt;br /&gt;pnlEditUser     &lt;br /&gt;pnlChangePassword     &lt;br /&gt;pnlConfirmResetPassword     &lt;br /&gt;pnlChangeSecurityQA     &lt;br /&gt;pnlChangeUsername     &lt;br /&gt;pnlDeleteRoleConfirmation     &lt;br /&gt;pnlChangeRoleName     &lt;br /&gt;pnlChangeRoleNameConfirm&lt;/p&gt;  &lt;p&gt;And one more time add the property and assign the values. Add the following to the backend code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private _ModalPopupCssClass As String      &lt;br /&gt;Public Property ModalPopupCssClass() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _ModalPopupCssClass       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _ModalPopupCssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlMessageDialog.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlDeleteUserConfirm.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlCreateUser.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlEditUser.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlChangePassword.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlConfirmResetPassword.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlChangeSecurityQA.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlChangeUsername.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlDeleteRoleConfirmation.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlChangeRoleName.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pnlChangeRoleNameConfirm.CssClass = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Check it if you want, my control is staring to look pretty odious (I’m choosing some truly awful colors, just for kicks).&lt;/p&gt;  &lt;p&gt;For the remaining CssClasses, we have a number of other one-off’s that we’ll need to address individually. I won’t be addressing them in this post, but I’ll list them and then you can add the property code to assign their classes just as we did above. The controls I cataloged were:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;tblSearchUsers      &lt;br /&gt;tblSearchUsersHeader       &lt;br /&gt;tblSearchUsersBody       &lt;br /&gt;gvManageUsers – CssClass, RowStyleCssClass, AlternativeRowStyleCssClass       &lt;br /&gt;tblCreateUser       &lt;br /&gt;tblCreateRole       &lt;br /&gt;tblCreateRoleHeader       &lt;br /&gt;gvRoles – CssClass, RowStyleCssClass, AlternativeRowStyleCssClass       &lt;br /&gt;tblSearchForUsersRole       &lt;br /&gt;tblSearchForUsersRoleBody       &lt;br /&gt;gvUsersForRole – CssClass, RowStyleCssClass, AlternativeRowStyleCssClass&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Two notes: 1. Some of these can likely be combined (such as the GridView’s CssClasses) since I want them to look the same I’ll set them the same time, 2. If you go back trough your code, you’ll notice that the tables and the Header and Body elements here listed (i.e. tblSearchUsers and tblSearchUsersHeader), may need to have an ID attached to them so we can call them in the back-end code (they may not already have ID’s). This means that you’ll be adding an ID to a table (tblSearchUsers) and to a TableCell (tblSearchUsersHeader – as it isn’t truly a header, it’s a TableCell masquerading as one) in your front-end code so you can call it directly in the back-end. Then we’ll create a property that calls it a header (i.e. headerCssClass) – so even some child elements will have ID’s assigned. Create and assign the properties as you did above.&lt;/p&gt;  &lt;p&gt;Realistically, any CSS that we created in the front-end, you can setup as a property and override as you desire.&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;Real-time Username Notification&lt;/p&gt;  &lt;p&gt;One of the things I thought would be really great to have from the get go was to add real-time username availability notification. What I mean by that is for those locations where the admin creates or changes the username, allow the dialog to inform the admin whether the username is available AS they are typing. Something akin to &lt;a href="http://mosesofegypt.net/post/UsernameAvailabilityValidatorAJAXControlReleaseDemo.aspx"&gt;this&lt;/a&gt; (and the actual demo &lt;a href="http://mosesofegypt.net/samples00/usernameavailability/CreateUser.aspx"&gt;here&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;When I started this project, the authors weren’t fully finished with develpment, but they did finish by the time I finished our control. Unfortunately (in our instance), they created a user control. BUT, wanting to put my control together as a &lt;u&gt;self-contained&lt;/u&gt; usercontrol, I didn’t want to add another external control to the mix. I looked into reusing the code and integrating it into my control, and it could be done. What I didn’t think about though is that the front-end page needs to call to &lt;em&gt;something&lt;/em&gt;, via Javascript/AJAX as you are typing. Any way it is sliced, (at least from what I found on the site) this requires a web service of some kind on the back-end (that’s the &lt;em&gt;something&lt;/em&gt;). Even if I can call a function contained in the same page (which the control alas is NOT, it’s a control not a page), it has to be declared as a web service so that it can be called by the AJAX (there’s an interesting article on &lt;a href="http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/"&gt;using jQuery to call a page method&lt;/a&gt; that I read).&lt;/p&gt;  &lt;p&gt;To get it to work, the jQuery has to call a page, by name, and then the method (we could pass the page name to the control by property in the front-end and write it into our javascript code so the jQuery can call it (&lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2007/01/05/Using-ASP.Net-to-Create-JavaScript-Variables.aspx"&gt;I’ve written on injecting into javascript before&lt;/a&gt;). We also would have to enable the page to support web services, which I gather necessitates some changes to the web.config. This then means that we’re not self contained. We have already broken our self contained requirement by adding functionality for changing the username (and will again in the next section), but realistically, to get this functioning, wasn’t worth the time I thought I’d end up putting in. The admin will get notification that the username is not available, it just won’t be while typing.&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;Role Descriptions&lt;/p&gt;  &lt;p&gt;Here’s another interesting bit of functionality that Microsoft left out (and I can’t discern why). Let’s say we want to put in a description of the role so that the admin can go back and remember what each role is meant for (the roles I’m using are descriptive to departments here at the company, but not necessarily to what rights the user gets). Descriptions would be handy. What to do? Well if you examine the roles table in the database, you’ll see that Microsoft conveniently added a description field to the database (nvarchar 256). So it seems that we’d be able to pretty easily enter a description. NOPE. Apparently, this is unimplemented functionality. There is nothing in the role provider to facilitate this. If we want to do it, we’ll have to again break our self-contained directive, and add some database functionality. We can create a property that we’ll use to specify whether the external functionality has been created like we did with our Change Username functionality. But, alas it means breaking the self-contained directive AGAIN.&lt;/p&gt;  &lt;p&gt;I’m going break our directive anyway, I believe it will have enough use for me that I’ll go ahead and break our rules again. First we need to start with modifying the front-end code. We want to add another column to our Manage Roles GridView. Add the following to the definition of gvRoles. Add it between the RoleName and 'Assign Users’ columns (as the 2nd column):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;asp:TemplateField HeaderText=&amp;quot;Description&amp;quot; Visible=&amp;quot;false&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;HeaderStyle HorizontalAlign=&amp;quot;Left&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:label runat=&amp;quot;server&amp;quot; ID=&amp;quot;lblRoleDescription&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;&amp;lt;%# GetRoleDescription(Container.DataItem.ToString()) %&amp;gt;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&amp;lt;asp:LinkButton runat=&amp;quot;server&amp;quot; ID=&amp;quot;lnkRoleDescription&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ForeColor=&amp;quot;Black&amp;quot; Text='Edit'       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CommandName=&amp;quot;EditRoleDescription&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CommandArgument='&amp;lt;%# Container.DataItem.ToString() %&amp;gt;'&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; OnCommand=&amp;quot;RoleLinkButtonClick&amp;quot;/&amp;gt;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ItemTemplate&amp;gt;       &lt;br /&gt;&amp;lt;/asp:TemplateField&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You’ll notice that we setup another column for the description, it is composed of 2 parts, a label for the description, and an edit link (you may notice that the control for that is surrounded by parentheses, that’s not a typo, they’re string literals for the HTML). You’ll also notice that we call a function GetRoleDescription. We’ll have to define that in our back-end code later. We also set the column’s visible property false so by default it is NOT shown. I put two controls in our column, one that displays the description name, and one that displays an edit link.&lt;/p&gt;  &lt;p&gt;Originally, I thought to put the description functionality with the change role name functionality, however I rethought that, as the change role name is already a special circumstance. We’ll keep them separate which means we’ll add another dialog for changing the description. As for adding a description when the admin creates a role, since the description functionality is not out of the box, I’ll force the admin to create a new role and then take a second step to enter a description.&lt;/p&gt;  &lt;p&gt;We’ll want to create a new modal dialog for editing our role description. Add the following to the bottom of our front-end code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;%-- Change Role description Dialog --%&amp;gt;      &lt;br /&gt;&amp;lt;asp:UpdatePanel id=&amp;quot;upnlRoleDescription&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160; ChildrenAsTriggers=&amp;quot;true&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ContentTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlRoleDescription&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; style=&amp;quot;display: none;&amp;quot; CssClass=&amp;quot;modalPopup&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HorizontalAlign=&amp;quot;Center&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Enter a description for the '&amp;lt;asp:label id=&amp;quot;lblRoleDescriptionName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;&amp;quot; /&amp;gt;' role.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Table ID=&amp;quot;Table1&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Role description:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Left&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TextBox ID=&amp;quot;txtRoleDescription&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:TextBoxWatermarkExtender ID=&amp;quot;tweRoleDescription&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;txtRoleDescription&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkText=&amp;quot;Enter role description.&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkCssClass=&amp;quot;watermarked&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Table&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkRoleDescriptionSave&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CausesValidation=&amp;quot;true&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Save&amp;quot; /&amp;gt;&amp;amp;nbsp;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkRoleDescriptionCancel&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Cancel&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Panel&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button ID=&amp;quot;btnFakeMPERoleDescription&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; style=&amp;quot;display: none;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:ModalPopupExtender id=&amp;quot;mpeRoleDescription&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;btnFakeMPERoleDescription&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PopupControlID=&amp;quot;pnlRoleDescription&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BackgroundCssClass=&amp;quot;modalBackground&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ContentTemplate&amp;gt;       &lt;br /&gt;&amp;lt;/asp:UpdatePanel&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It’s pretty standard for our dialogs. We have one TextBox, for the description and two LinkButtons for save and cancel. In keeping with previous dialogs, let’s display this using our SetUI subroutine. Add the following to our SetUI enumeration:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;EnableRoleDescription      &lt;br /&gt;RoleDescriptionDialog&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Then we’ll add some functionality to our SetUI subroutine. Add the following two cases to your SetUI case statement:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Case SetUIModes.EnableRoleDescription      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; gvRoles.Columns(1).Visible = True       &lt;br /&gt;Case SetUIModes.RoleDescriptionDialog       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; mpeRoleDescription.Show()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This just takes care of displaying things. The first case will make our column visible if the property is set to true. The second shows the dialog. We’ll also need to add some functionality to our RoleLinkButtonClick event handler. Add the following If statement to your RoleLinkiButtonClick:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;If e.CommandName.Equals(&amp;quot;EditRoleDescription&amp;quot;) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblRoleDescriptionName.Text = CStr(e.CommandArgument)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; txtRoleDescription.Text = GetRoleDescription(e.CommandArgument)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetUI(SetUIModes.RoleDescriptionDialog)       &lt;br /&gt;End If&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This will set the textbox to the current role description and then show the edit dialog when the admin clicks the ‘Edit’ link.&lt;/p&gt;  &lt;p&gt;Next, let’s setup the save and cancel buttons in the role description dialog. Add the following to your back-end code to your lnkRoleDescriptionCancel_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;txtRoleDescription.Text = String.Empty&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This simply clears our TextBox if we cancel so we don’t have any loose ends. Next add the following to our lnkRoleDescriptionSave_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;If UpdateRoleDescription(lblRoleDescriptionName.Text, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; txtRoleDescription.Text) = True Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblMessageDialog.Text = &amp;quot;Role description successfully updated.&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetUI(SetUIModes.MessageDialog)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; gvRoles.DataSource = Roles.GetAllRoles()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; gvRoles.DataBind()       &lt;br /&gt;Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblMessageDialog.Text = &amp;quot;Changing the role's description was _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; unsuccessful.&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetUI(SetUIModes.MessageDialog)       &lt;br /&gt;End If&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Here we call a UpdateRoleDescription subroutine and pass it the role’s name and the new description. If it returns successful, we’ll rebind the GridView with new data, and display a success message. If it fails, we’ll display a failure message. In our SQL code, we will be retrieving the role by the role’s name. Since we won’t be allowed by our provider to add a role name more than once per ApplicationID (more on that later), we should be ok doing it this way.&lt;/p&gt;  &lt;p&gt;We’ll need to define some SQL before proceeding. We’ll create two stored procedures for our database. First, let’s define the GetRoleDescription’s stored procedure:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;CREATE PROCEDURE aspnet_Roles_GetRoleDescription      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @RoleName nvarchar(255),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @ApplicationName nvarchar(255),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @RoleDescription nvarchar(255) OUTPUT       &lt;br /&gt;AS       &lt;br /&gt;DECLARE @ApplicationID nvarchar(255)       &lt;br /&gt;SELECT @ApplicationID = ApplicationID FROM aspnet_Applications       &lt;br /&gt;&amp;#160;&amp;#160; WHERE ApplicationName = @ApplicationName       &lt;br /&gt;      &lt;br /&gt;SELECT @RoleDescription = Description FROM aspnet_Roles       &lt;br /&gt;&amp;#160;&amp;#160; WHERE RoleName = @RoleName AND ApplicationID = @ApplicationID&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;First off, we create three SQL variables, two will be input and one output. The input variables will pass in our role name and our application name. We’ll use the application name to pull the ApplicationID and then use the role name and ApplicationID to target the description. We need to include the ApplicationID since we can create two roles with the same name in the database &lt;strong&gt;IF&lt;/strong&gt; they have different applications assigned to them. If we target by role name only, we could be effecting multiple roles, especially when we get to updating the role’s description. Finally we’ll retrieve the description and assign that to our output variable.&lt;/p&gt;  &lt;p&gt;Next, we’ll define our UpdateRoleDescription stored procedure as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;CREATE PROCEDURE aspnet_Roles_UpdateRoleDescription      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @RoleName nvarchar(255),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @ApplicationName nvarchar(255),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @RoleDescription nvarchar(255),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @Results bit OUTPUT       &lt;br /&gt;AS       &lt;br /&gt;DECLARE @ApplicationID nvarchar(255)       &lt;br /&gt;SELECT @ApplicationID = ApplicationID FROM aspnet_Applications       &lt;br /&gt;&amp;#160;&amp;#160; WHERE ApplicationName = @ApplicationName       &lt;br /&gt;      &lt;br /&gt;UPDATE aspnet_Roles SET Description = @RoleDescription       &lt;br /&gt;&amp;#160;&amp;#160; WHERE RoleName = @RoleName AND ApplicationID = @ApplicationID       &lt;br /&gt;      &lt;br /&gt;SET @Results = @@ROWCOUNT&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This time we’re creating three input variables, since we need to pass in the new description as well as the role name and application name. Much like the previous stored procedure, we’ll use the application name to retrieve the ApplicationID and then use that to target the correct role. Then we update the description for the role and return the affected row count as a result. This way, we can check the success of our operation. We should only get a 1 back (meaning one row affected). If we get anything else, we’ll have failed.&lt;/p&gt;  &lt;p&gt;Now we’re ready to do some hookups in the back-end code. First, we’ll define our GetRoleDescription function. Add the following function to your back-end code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Function GetRoleDescription(ByVal sRoleName As String, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Optional ByVal iOrdinalForConnectionString As Integer = 0) As String&amp;#160;&amp;#160; &lt;br /&gt;      &lt;br /&gt;&lt;font color="#ff0000"&gt;&lt;font color="#000000"&gt;&amp;#160; &lt;/font&gt;&lt;strong&gt;If _RoleDescriptionFunctionality = _         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RoleDescriptionSettings.DbIsSetup Then&lt;/strong&gt;&lt;/font&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Using cn As New SqlConnection(ConfigurationManager.ConnectionStrings       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (iOrdinalForConnectionString).ConnectionString)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim cmd As New SqlCommand(&amp;quot;aspnet_Roles_GetRoleDescription&amp;quot;, cn)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.CommandType = Data.CommandType.StoredProcedure       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add(&amp;quot;@RoleName&amp;quot;, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Data.SqlDbType.NVarChar).Value = sRoleName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add(&amp;quot;@ApplicationName&amp;quot;, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Data.SqlDbType.NVarChar).Value = Roles.ApplicationName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add(&amp;quot;@RoleDescription&amp;quot;, Data.SqlDbType.NVarChar, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 255).Direction = Data.ParameterDirection.Output       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#ff0000"&gt;&lt;strong&gt;&lt;strike&gt;cn.Open()&lt;/strike&gt;&lt;/strong&gt;&lt;/font&gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Try       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#ff0000"&gt;&lt;strong&gt;cn.Open()&lt;/strong&gt;&lt;/font&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.ExecuteScalar()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Catch ex As Exception       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return string.empty       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Finally       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cn.Close()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Try       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If cmd.Parameters(&amp;quot;@RoleDescription&amp;quot;).Value.Equals _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (System.DBNull.Value) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return String.Empty       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return cmd.Parameters(&amp;quot;@RoleDescription&amp;quot;).Value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Using      &lt;br /&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;&amp;#160; Else         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return String.Empty          &lt;br /&gt;&amp;#160; End If&lt;/font&gt;&lt;/strong&gt;       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In the parameter list for our function, you’ll notice we pass in our role name, and we also pass in an optional parameter for our connectionstring. If you remember back to &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx"&gt;part 5&lt;/a&gt; in the series, we added some database functionality for changing the username. I mentioned when we created the back-end code for ChangeUsername, that this was perhaps the least flexible part of our entire project, since we can’t automatically pull the current connectionstring from anywhere. We need to have a way to retrieve it so we can create a connection to our database though. Since the connectionstrings are in an array, we can specify them by ordinal number. In my simple application here at work, my connectionstring is 0 (the only one). To target another connectionstring for our connection, we would need to determine the ordinal number of the connectionstring and pass it in. (UGLY I agree… excuse me while I hurl…). We may be able to set this via property as we did above with cssClasses so that we don’t have to modify the code to change the connectionstring.&lt;/p&gt;  &lt;p&gt;The function creates a connection, and then a command object. We load the command object up with our parameters. Nothing fancy, except one item of note, we specify a size for the return parameter. If we don’t specify the size, our application will return an error about not allowing a string of size 0. We’ll then open the connection and try to execute. We’ll use a try catch and if we get an error, we’ll return an empty string. If we’re successful, we’ll check to see if we got a null value returned. If so, we’ll again return an empty string. If it’s NOT null, we’ll return the description.&lt;/p&gt;  &lt;p&gt;Next, let’s define our UpdateRoleDescription function:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Function UpdateRoleDescription(ByVal sRoleName As String, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal sNewDescription As String, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Optional ByVal iOrdinalForConnectionString As Integer = 0) As Boolean       &lt;br /&gt;      &lt;br /&gt;Using cn As New SqlConnection(ConfigurationManager.ConnectionStrings _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (iOrdinalForConnectionString).ConnectionString)&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim cmd As New SqlCommand(&amp;quot;aspnet_Roles_UpdateRoleDescription&amp;quot;, cn)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; cmd.CommandType = Data.CommandType.StoredProcedure       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add(&amp;quot;@RoleName&amp;quot;,_&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Data.SqlDbType.NVarChar).Value = sRoleName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add(&amp;quot;@ApplicationName&amp;quot;, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Data.SqlDbType.NVarChar).Value = Roles.ApplicationName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add(&amp;quot;@RoleDescription&amp;quot;, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Data.SqlDbType.NVarChar, 255).Value = sNewDescription       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add(&amp;quot;@Results&amp;quot;, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Data.SqlDbType.Bit).Direction = Data.ParameterDirection.Output       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; cn.Open()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Try       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.ExecuteNonQuery()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Catch ex As Exception       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Finally       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cn.Close()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Try       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return cmd.Parameters(&amp;quot;@Results&amp;quot;).Value       &lt;br /&gt;End Using       &lt;br /&gt;End Function       &lt;br /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Here we’re passing in three parameters, our role name, our new description name, and again our odious connectionstring ordinal. We create a connection and a command, load it up with our data, and then execute the query. If it fails, we return false, if it runs, we’ll return the result (if it fails, it’ll be false that gets returned).&lt;/p&gt;  &lt;p&gt;Viola, now we can add role descriptions. Why Microsoft hasn’t bothered to make this part of the Roles provider I’ll never know. I mean why build it into the database if you aren’t going to use it? Anyhow, Role descriptions at our disposal.&lt;/p&gt;  &lt;p class="MySubHeadings"&gt;Fixing Change Username Functions&lt;/p&gt;  &lt;p&gt;In the process of adding role description functionality, I found that I didn’t properly execute our ChangeUsername function. If you remember, in the above section, we passed in the applicationName so that we target only the Role that we want to. Technically, we can have more than one username or more than one role in a table &lt;strong&gt;if&lt;/strong&gt; we add it using a different applicationName. I didn’t take that into account when I put together ChangeUsername. I neglected to use the application name SO, technically the code would change ALL the usernames rather than just the one we want. Let’s make some changes so that it behaves properly. Let’s modify our ChangeUsername function to include an applicationName parameter. Add the following just below our @newUsername parameter in our ChangeUsername function:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;cmd.Parameters.Add(&amp;quot;@applicationName&amp;quot;, _      &lt;br /&gt;&amp;#160;&amp;#160; Data.SqlDbType.NVarChar).Value = Membership.ApplicationName&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And then we’ll need to modify our aspnet_Membership_ChangeUsername stored procedure. The SQL to update the stored procedure is as follows (changes are in bold):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;ALTER PROCEDURE aspnet_Membership_ChangeUsername      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @currentUsername nvarchar(255),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @newUsername nvarchar(255),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;@applicationName nvarchar(255),&lt;/strong&gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @results bit OUTPUT       &lt;br /&gt;AS       &lt;br /&gt;      &lt;br /&gt;&lt;strong&gt;DECLARE @ApplicationID nvarchar(255)        &lt;br /&gt;SELECT @ApplicationID = ApplicationID FROM aspnet_Applications         &lt;br /&gt;&amp;#160;&amp;#160; WHERE ApplicationName = @ApplicationName&lt;/strong&gt;&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; UPDATE aspnet_Users       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SET UserName = @newUsername,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LoweredUserName = LOWER(@newUsername)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WHERE LOWER(UserName) = LOWER(@currentUsername)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;AND ApplicationID = @ApplicationID&lt;/strong&gt;       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; set @results = @@ROWCOUNT&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;There, now we properly target our specific username.&lt;/p&gt;  &lt;p&gt;One other thing I want to update is to reset the change username dialog when the admin clicks cancel. To do this, all we need to do is add two lines to our lnkChangeUsername_Click event handler. Add these lines right after the End If line, and before the lblCurrentUsername.text line:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;txtNewUsername.Text = String.Empty      &lt;br /&gt;divUserAvailablity.InnerText = String.Empty&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Previously, if we canceled changing the username, the the new username textbox and an error message, if applicable, would be there when we reopened it. Now it won’t, it will be pristine like it’s supposed to be.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Epilogue &lt;/p&gt;  &lt;p&gt;And there it is, “A Better Asp.Net Member/Role Management Page”. There were a couple other tings I thought about adding to the mix, like rewriting all the confirmation dialogs so that there is one common dialog that we could reuse everywhere we confirmed things, but I didn’t really want to go through the trouble of rewriting the whole mess just to reduce the code, it wasn’t worth it.&lt;/p&gt;  &lt;p&gt;If anyone has something that &lt;u&gt;they&lt;/u&gt; added, that they’d like to tell us about, drop me a line and I’ll put it in the comments section. I’m sure we’d all love to see it.&lt;/p&gt;  &lt;p&gt;But for me, that’s it for the management page. I’ll be putting it into production now that I’m done writing it (yes, I was still finishing it), and unless there are any issues that people point out or errors that need corrected. I’m calling it good and being done! PHEW!&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx&amp;amp;;subject=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+7" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx&amp;amp;;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+7" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx&amp;amp;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+7" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx&amp;amp;;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+7" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx&amp;amp;;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+7&amp;amp;;top=1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/03/30/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-7.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://aspadvice.com/aggbug.aspx?PostID=51872" width="1" height="1"&gt;</description></item><item><title>A Better ASP.Net Member/Role Management Page Pt. 6</title><link>http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx</link><pubDate>Wed, 21 Jan 2009 07:47:25 GMT</pubDate><guid isPermaLink="false">e709ad4c-0c15-48eb-915e-c462c6e85445:50299</guid><dc:creator>Yougotiger</dc:creator><slash:comments>5</slash:comments><comments>http://aspadvice.com/blogs/net_discoveries/comments/50299.aspx</comments><wfw:commentRss>http://aspadvice.com/blogs/net_discoveries/commentrss.aspx?PostID=50299</wfw:commentRss><wfw:comment>http://aspadvice.com/blogs/net_discoveries/rsscomments.aspx?PostID=50299</wfw:comment><description>&lt;p class="MyHeadings"&gt;Prologue&lt;/p&gt;  &lt;p&gt;**Author Note – If you are bewildered by a line (perhaps two) that are red and bold, don’t they that they’re errors, they are corrections/additions. Please see the comments, after the article for comments regarding the highlighted line(s).**&lt;/p&gt;  &lt;p&gt;In previous posts, we started creating “A Better ASP.Net Member/Role Management Page.” In &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/09/29/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-1.aspx"&gt;part 1&lt;/a&gt;, we defined our criteria, and in &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/10/07/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-2.aspx"&gt;part 2&lt;/a&gt;, &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/10/14/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-3.aspx"&gt;part 3&lt;/a&gt;, &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/11/06/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-4.aspx"&gt;part 4&lt;/a&gt; and &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx"&gt;part 5&lt;/a&gt; we created functionality to do all our user maintenance. In this section, we work on our role maintenance functionality.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Problem&lt;/p&gt;  &lt;p&gt;We actually have a fair amount of things to do to maintain roles. We’ll create a grid much like the one for the user list, for the roles. We’ll also create a user GridView, so when we select a role, we can search the users and assign them to the given role (much like the user search functionality that we’ve already created. We’ll also need to create a number of dialog boxes that we can popup to get information or confirmation from the administrator. Once we’re finished, we’ll have functionality to add/remove, assign and change role names.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Solution&lt;/p&gt;  &lt;p&gt;First things first. We need to create some user interface portions. Add the following two sections to your front-end code somewhere between our pnlFormatEverything tags:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;%-- Manage Roles --%&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;asp:UpdatePanel ID=&amp;quot;upnlManageRoles&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ChildrenAsTriggers=&amp;quot;true&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ContentTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlManageRoles&amp;quot; runat=&amp;quot;server&amp;quot; Visible=&amp;quot;false&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblManageRolesTitle&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;br /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblManageRolesInstructions&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Select &amp;lt;b&amp;gt;Edit Role&amp;lt;/b&amp;gt; to view or change the       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; settings for the roles.&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Table ID=&amp;quot;tblCreateRole&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CssClass=&amp;quot;tableBorders&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell CssClass=&amp;quot;tableHeadersNTitles&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Literal ID=&amp;quot;lblCreateRoleTile&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Create New Role:&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblCreateRole&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;New Role Name:&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TextBox runat=&amp;quot;server&amp;quot; ID=&amp;quot;txtNewRoleName&amp;quot;/&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:TextBoxWatermarkExtender ID=&amp;quot;tweNewRole&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;txtNewRoleName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkCssClass=&amp;quot;watermarked&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkText=&amp;quot;Enter new role name&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button id=&amp;quot;btnAddRole&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Add Role&amp;quot;/&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Table&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:GridView runat=&amp;quot;server&amp;quot; CellPadding=&amp;quot;3&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GridLines=&amp;quot;Horizontal&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID=&amp;quot;gvRoles&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CssClass=&amp;quot;userGridView&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AutoGenerateColumns=&amp;quot;false&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AllowPaging=&amp;quot;true&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PageSize=&amp;quot;7&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; UseAccessibleHeader=&amp;quot;true&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;RowStyle CssClass=&amp;quot;gridRowStyle&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;AlternatingRowStyle CssClass=&amp;quot;gridAlternatingRowStyle&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;PagerStyle CssClass=&amp;quot;gridPagerStyle&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;PagerSettings mode=&amp;quot;Numeric&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;HeaderStyle CssClass=&amp;quot;tableHeadersNTitles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Font-Bold=&amp;quot;true&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Columns&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TemplateField HeaderText=&amp;quot;Role Name&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;HeaderStyle HorizontalAlign=&amp;quot;Left&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label runat=&amp;quot;server&amp;quot; ID=&amp;quot;lblRoleName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ForeColor=&amp;quot;Black&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text='&amp;lt;%# Container.DataItem.ToString() %&amp;gt;' /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TemplateField&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TemplateField&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;HeaderStyle HorizontalAlign=&amp;quot;Center&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkManageUsersInRole&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Assign Users&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CommandName=&amp;quot;EditUsersInRole&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CommandArgument='&amp;lt;%#       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Container.DataItem.ToString() %&amp;gt;' ForeColor=&amp;quot;Black&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; OnCommand=&amp;quot;RoleLinkButtonClick&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TemplateField&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TemplateField&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkDeleteRole&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Delete Role&amp;quot; CommandName=&amp;quot;DeleteRole&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CommandArgument='&amp;lt;%# Container.DataItem.ToString() %&amp;gt;'       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ForeColor=&amp;quot;Black&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; OnCommand=&amp;quot;RoleLinkButtonClick&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TemplateField&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TemplateField&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;HeaderStyle HorizontalAlign=&amp;quot;Left&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkEditRoleName&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Change Role Name&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CommandName=&amp;quot;EditRoleName&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CommandArgument='&amp;lt;%# Container.DataItem.ToString() %&amp;gt;'       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ForeColor=&amp;quot;Black&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; OnCommand=&amp;quot;RoleLinkButtonClick&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TemplateField&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Columns&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:GridView&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label runat=&amp;quot;server&amp;quot; ID=&amp;quot;lblNoRoles&amp;quot; Visible=&amp;quot;false&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;No roles have been created.&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkManagerUsers&amp;quot;&amp;#160; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Manager Users&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Panel&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ContentTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:UpdatePanel&amp;gt;&amp;#160; &lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;%-- Assign/Remove Users from Role --%&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;asp:UpdatePanel ID=&amp;quot;upnlAddRemoveUsersFromRole&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; ChildrenAsTriggers=&amp;quot;true&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ContentTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlAddRemoveUsersFromRole&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Visible=&amp;quot;false&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblAddRemoveUsersFromRoleTitle&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;br /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblAddRemoveUsersFromRoleInstructions&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Use this page to manage the members in the specified role. To add a user to the role, search for the user name and then select User Is In Role for that user. &amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Role:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;b&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Literal runat=&amp;quot;server&amp;quot; ID=&amp;quot;lblRoleToAddRemoveUsersTo&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/b&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Table id=&amp;quot;tblSearchForUsersRole&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CssClass=&amp;quot;tableBorders&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Literal ID=&amp;quot;lblSearchForUsersRole&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Search For Users&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell CssClass=&amp;quot;tableBody&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label id=&amp;quot;lblSearchForUsersRoleSearchBy&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Search By: &amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:DropDownList ID=&amp;quot;ddlSearchForUsersRole&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:ListItem id=&amp;quot;item3&amp;quot; Text=&amp;quot;Username&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:ListItem id=&amp;quot;item4&amp;quot; Text=&amp;quot;Email&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:DropDownList&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;amp;nbsp;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblSearchForRoles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;for: &amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TextBox id=&amp;quot;txtSearchUsersForRoles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; /&amp;gt;&amp;amp;nbsp;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:TextBoxWatermarkExtender       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID=&amp;quot;tweSearchUsersForRoles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;txtSearchUsersForRoles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkCssClass=&amp;quot;watermarked&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkText=&amp;quot;Enter criteria&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button id=&amp;quot;btnSearchUsersForRoles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Search For&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label runat=&amp;quot;server&amp;quot; ID=&amp;quot;lblWildcardAllowed&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Wildcards * and ? are permitted.&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Repeater runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID=&amp;quot;rptAlphabetRepeaterRoles&amp;quot; &amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton runat=&amp;quot;server&amp;quot; id=&amp;quot;lnkLetterRoles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CommandName=&amp;quot;Display&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CommandArgument=&amp;quot;&amp;lt;%# Container.DataItem %&amp;gt;&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;&amp;lt;%# Container.DataItem %&amp;gt;&amp;quot; /&amp;gt;&amp;amp;nbsp;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Repeater&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Table&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:GridView runat=&amp;quot;server&amp;quot; CellPadding=&amp;quot;3&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GridLines=&amp;quot;Horizontal&amp;quot; ID=&amp;quot;gvUsersForRole&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CssClass=&amp;quot;userGridView&amp;quot; AutoGenerateColumns=&amp;quot;false&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AllowPaging=&amp;quot;true&amp;quot; PageSize=&amp;quot;7&amp;quot; UseAccessibleHeader=&amp;quot;true&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;RowStyle CssClass=&amp;quot;gridRowStyle&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;AlternatingRowStyle CssClass=&amp;quot;gridAlternatingRowStyle&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;PagerStyle CssClass=&amp;quot;gridPagerStyle&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;PagerSettings mode=&amp;quot;Numeric&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;HeaderStyle CssClass=&amp;quot;tableHeadersNTitles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Font-Bold=&amp;quot;true&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Columns&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TemplateField HeaderText=&amp;quot;Username&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;HeaderStyle HorizontalAlign=&amp;quot;Left&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblUsernameRole&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ForeColor=&amp;quot;Black&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;&amp;lt;%# Container.DataItem %&amp;gt;&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TemplateField&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TemplateField HeaderText=&amp;quot;User is in role&amp;quot;&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;HeaderStyle HorizontalAlign=&amp;quot;Center&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemStyle HorizontalAlign=&amp;quot;Center&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:CheckBox runat=&amp;quot;server&amp;quot; ID=&amp;quot;chkUserInRole&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; OnCheckedChanged=&amp;quot;ChangeUserIsAssignedToRole&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AutoPostBack=&amp;quot;true&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Checked='&amp;lt;%# IsUserInRole(Container.DataItem) %&amp;gt;' /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ItemTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TemplateField&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Columns&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:GridView&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label runat=&amp;quot;server&amp;quot; ID=&amp;quot;lblNoUsersFoundRoles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; visible=&amp;quot;false&amp;quot; EnableViewState=&amp;quot;false&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;No users found for this search.&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton runat=&amp;quot;server&amp;quot; ID=&amp;quot;lnkManageAllRoles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Manage All Roles&amp;quot; /&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton runat=&amp;quot;server&amp;quot; ID=&amp;quot;lnkManageUsersFromRoles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Manage Users&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Panel&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ContentTemplate&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160; &amp;lt;/asp:UpdatePanel&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You may want to put it towards the top, because putting it to the bottom will cause it to actually display too far toward the bottom. This is due to the fact that a lot of the other sections are styled with display:none. Doing this will leave a section of the rendered page for the sections’ outputs (even if they’re hidden) and push our role management stuff down so it looks weird. Since the other sections are mostly modal dialogs, we can put them at the bottom and they’ll still work as designed.&lt;/p&gt;  &lt;p&gt;Before we get to far into it, we’ll also want to add some stuff to our SetUI code block. We’ll be managing a number of panels and UI pieces on various clicks, so let’s add the following to our SetUIModes enumeration:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;EditUsersInRole      &lt;br /&gt;ManageAllRoles       &lt;br /&gt;DeleteRoleConfirm       &lt;br /&gt;RenameRoleConfirm       &lt;br /&gt;RenameRole&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and the following case statements to our SetUI case statement:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Case SetUIModes.EditUsersInRole      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; pnlManageRoles.Visible = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; pnlAddRemoveUsersFromRole.Visible = True       &lt;br /&gt;Case SetUIModes.ManageUsers ‘this line may exist already in your code…       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; pnlManageRoles.Visible = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; pnlAddRemoveUsersFromRole.Visible = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; pnlManageUsers.Visible = True       &lt;br /&gt;Case SetUIModes.ManageAllRoles       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; pnlManageRoles.Visible = True       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; pnlManageUsers.Visible = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; pnlAddRemoveUsersFromRole.Visible = False       &lt;br /&gt;Case SetUIModes.DeleteRoleConfirm       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; mpeDeleteRoleConfirm.Show()       &lt;br /&gt;Case SetUIModes.RenameRoleConfirm       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; mpeRoleRenameConfirm.Show()       &lt;br /&gt;Case SetUIModes.RenameRole       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; mpeChangeRoleName.Show()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You may have noticed that we previously (in &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/10/14/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-3.aspx"&gt;part 3&lt;/a&gt;) created a case statement for ManageUsers, we just never populated the code for the case. We can now add this functionality, so just add the code for that case as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;pnlManageRoles.Visible = False      &lt;br /&gt;pnlAddRemoveUsersFromRole.Visible = False       &lt;br /&gt;pnlManageUsers.Visible = True&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now we can get down to coding the pieces we need to make it all functional. First we’ll want to enable the ‘Manage Roles’ link so that we can access our manage role information. This is pretty easy, add the following to your lnkManageRoles_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;SetUI(SetUIModes.ManageAllRoles)      &lt;br /&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;SetDataSource(Roles.GetAllRoles, ROLES_DATA_SOURCE)          &lt;br /&gt;BindGrid(gvRoles, ROLES_DATA_SOURCE, True)           &lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;      &lt;br /&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;&lt;strike&gt;gvRoles.DataSource = Roles.GetAllRoles()            &lt;br /&gt;gvRoles.DataBind()&lt;/strike&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This will hide our user GridView, and display our Roles GridView. In addition, it will &lt;strong&gt;&lt;font color="#ff0000"&gt;store our datasource and then&lt;/font&gt;&lt;/strong&gt; populate our Roles GridView with all the roles in the database.&lt;/p&gt;  &lt;p&gt;Continuing with the easy stuff, once we switch over to the Manage Roles side, we’ll have a link that takes us back to managing users, we should also hook that up. Add the following to your lnkManageUsers_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;SetUI(SetUIModes.ManageUsers)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Really all we’re doing is hiding one and showing the other, not much to it.&lt;/p&gt;  &lt;p&gt;Next, let’s hook up our Add Role functionality. Add the following to your btnAddRole_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Try      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Roles.CreateRole(txtNewRoleName.Text)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; txtNewRoleName.Text = String.Empty       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; gvRoles.DataSource = Roles.GetAllRoles()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; gvRoles.DataBind()       &lt;br /&gt;Catch ex As Exception       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblMessageDialog.Text = ex.Message       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetUI(SetUIModes.MessageDialog)       &lt;br /&gt;End Try&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is a little more complex, but still pretty simple. We put our attempt to add the role within a try catch block so that if something goes wrong: A. it doesn’t crash, and B. we can let the administrator know what the matter is. We’ll first attempt to create the role, if we get an error, this is where it will happen. If adding the role is successful, then we’ll clear the textbox, and then rebind our GridView with fresh data. If adding the role fails, we’ll display our message dialog box, and show the administrator the error that was returned in the exception.&lt;/p&gt;  &lt;p&gt;Next, we’ll concentrate on the links in each row of the GridView. Let’s start with the ‘Delete Role’ link. If you notice in our front-end code, each or our links in the row of our GridView calls ‘RoleLinkButtonClick’ when they are clicked. This means that we’ll need to create a RoleLinkButtonClick event handler in our code. We’ll need to include information typical to an event handler as far as parameters are concerned. Since all the links call the same event handler, we’ll need to&amp;#160; determine which was selected, we’ll use a if then statements for that. Create your event handler as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Sub RoleLinkButtonClick(ByVal sender As Object, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ByVal e As CommandEventArgs)&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160; ‘&lt;strike&gt;If e.&lt;font color="#ff0000"&gt;&lt;strong&gt;CommandArgument&lt;/strong&gt;&lt;/font&gt;.Equals(&amp;quot;DeleteRole&amp;quot;) Then&lt;/strike&gt;       &lt;br /&gt;&amp;#160;&amp;#160; If e.&lt;font color="#ff0000"&gt;&lt;strong&gt;CommandName&lt;/strong&gt;&lt;/font&gt;.Equals(&amp;quot;DeleteRole&amp;quot;) Then       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; End If       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We’ve just created a shell for our event handler and for our delete role section of it. Before we actually delete anything we’ll want to confirm with the administrator that they want to delete the role. We’ll need to create a confirmation dialog in our front-end so that we can display it. Add the following to your front-end code. It is a dialog, so it can go towards the bottom if you so desire:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;%-- Delete Role Confirmation Dialog --%&amp;gt;      &lt;br /&gt;&amp;lt;asp:UpdatePanel ID=&amp;quot;upnlDeleteRoleConfirmation&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ChildrenAsTriggers=&amp;quot;true&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;ContentTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlDeleteRoleConfirmation&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CssClass=&amp;quot;modalPopup&amp;quot; style=&amp;quot;display:none; text-align:center;&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Literal runat=&amp;quot;server&amp;quot; ID=&amp;quot;lblDeleteRoleConfirmMessage&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Literal runat=&amp;quot;server&amp;quot; ID=&amp;quot;lblRoleToDelete&amp;quot; Visible=”False” /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br&amp;gt;&amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button runat=&amp;quot;server&amp;quot; ID=&amp;quot;btnDeleteRoleYes&amp;quot; Text=&amp;quot;Yes&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;amp;nbsp;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button runat=&amp;quot;server&amp;quot; ID=&amp;quot;btnDeleteRoleNo&amp;quot; Text=&amp;quot;No&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Panel&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID=&amp;quot;btnFakeShowMPEDeleteRoleConfirmButton&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; style=&amp;quot;display: none;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:ModalPopupExtender ID=&amp;quot;mpeDeleteRoleConfirm&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;btnFakeShowMPEDeleteRoleConfirmButton&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PopupControlID=&amp;quot;pnlDeleteRoleConfirmation&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BackgroundCssClass=&amp;quot;modalBackground&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;/ContentTemplate&amp;gt;       &lt;br /&gt;&amp;lt;/asp:UpdatePanel&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We create a dialog, not much of note, a yes and a no button. The one exception is a hidden literal control that we can use to later pull the associated username. With the dialog complete, we can add the innards to our event handler. Add the following to the If statement for ‘DeleteRole’:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;lblRoleToDelete.Text = CStr(e.CommandArgument)      &lt;br /&gt;lblDeleteRoleConfirmMessage.Text = &amp;quot;Are you sure you want to delete role: &amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160; &amp;amp; lblRoleToDelete.Text       &lt;br /&gt;SetUI(SetUIModes.DeleteRoleConfirm)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This just loads up our dialog, and then show it. Now we need to hookup our ‘Yes’ and ‘No’ buttons. First, let’s hookup our ‘No’ button, add the following to our btnDeleteRoleNo_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;mpeDeleteRoleConfirm.Hide()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Basically, we just hide the dialog when the user clicks ‘No’. Now, for our ‘Yes’ button, add the following to our btnDeleteRoleYes_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Try      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Roles.DeleteRole(lblRoleToDelete.Text)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; gvRoles.DataSource = Roles.GetAllRoles()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; gvRoles.DataBind()       &lt;br /&gt;Catch ex As Exception       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblMessageDialog.Text = ex.Message()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetUI(SetUIModes.MessageDialog)       &lt;br /&gt;End Try&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Again, we’ve got a try catch block in case something terrible happens. We’ll attempt to delete the role, if it fails, we’ll jump to the catch portion of the bock and display the failure message. If it is successful, we’ll refresh the GridView and display the new data.&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Next, well hookup the functionality for assigning users to the role. First, we’ll want to setup a constant for our Users_In_Role datasource add the following constant to your back-end code:&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Private Const USERS_IN_ROLE_DATA_SOURCE As String = _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;USERS_IN_ROLE_DATA_SOURCE&amp;quot;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Then, we’ll setup a helper function to handle binding the users in role grid and accounting for an empty dataset. Add the following helper subroutine to your code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Sub BindUsersForRoleGrid()&amp;#160; &lt;br /&gt;&amp;#160; &lt;font color="#ff0000"&gt;&lt;strong&gt;&lt;strike&gt;gvUsersForRole.DataSource = theSession(ROLES_DATA_SOURCE&lt;/strike&gt;)&amp;#160; &lt;br /&gt;&amp;#160; gvUsersForRole.DataSource = _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; theSession(USERS_IN_ROLE_DATA_SOURCE)&lt;/strong&gt;&lt;/font&gt;       &lt;br /&gt;&amp;#160; gvUsersForRole.DataBind()&amp;#160; &lt;br /&gt;&amp;#160; If gvUsersForRole.Rows.Count = 0 Then&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblNoUsersFoundRoles.Visible = True&amp;#160; &lt;br /&gt;&amp;#160; End If       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We’re creating a subroutine that will populate our GridView’s data source and then examine the GridView. If it is empty, then we’ll show the message about no users being assigned to to the role.&lt;/p&gt;  &lt;p&gt;Now we’re ready to add the actual functionality for when we click the ‘Assign Users’ link in the role’s row. Add the following to your RoleLinkButtonClick event handler, after the End If for DeleteRole:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;If e.CommandName.Equals(&amp;quot;EditUsersInRole&amp;quot;) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblRoleToAddRemoveUsersTo.Text = CStr(e.CommandArgument)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; PopulateAlphabetRepeater(rptAlphabetRepeaterRoles)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&lt;font color="#ff0000"&gt;&lt;strike&gt;SetDataSource(Roles.GetUsersInRole _&amp;#160; &lt;br /&gt;&lt;/strike&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;strike&gt;(lblRoleToAddRemoveUsersTo.Text), ROLES_DATA_SOURCE)           &lt;br /&gt;&lt;/strike&gt;&amp;#160;&amp;#160;&amp;#160; SetDataSource(Roles.GetUsersInRole _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (lblRoleToAddRemoveUsersTo.Text), _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; USERS_IN_ROLE_DATA_SOURCE)           &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; BindUsersForRoleGrid()&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetUI(SetUIModes.EditUsersInRole)       &lt;br /&gt;End If&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;With that added, we should be able to click our ‘Assign Users’ link and have our ‘Users in Role’ GridView displayed (if there are users in the role). You’ll notice though, that there are a couple of links at the bottom to allow us to navigate back to other editing functions, but they don’t currently work. Let’s hook them up so we can return. Add the following to our lnkManageAllRoles_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;SetUI(SetUIModes.ManageAllRoles)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and add the following to our lnkManageUsersFromRoles_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;SetUI(SetUIModes.ManageUsers)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now we should be able to return to previous screens without problem. If you run our application, select to manage roles and then select to assign users to a role, only the users that are currently assigned to our role will be displayed in the GridView. To see other users and assign them to the role, we’ll need to hookup the functionality for the alphabet repeater and search portion at the top. First, let’s create a helper function. This function will take a MembershipUserCollection and convert it to a string array containing usernames. We’ll do this because when we pull Roles.GetUsersInRole, we’ll get a string array, but when we pull from the Membership.FindUser functions, we’ll get a MembershipUserCollection back. Since we’re binding both lists to the same GridView (depending on how we search), it’s a lot easier if they both go to our BindGrid as the same data types. So, add the helper function as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Function ConvertMUCollToStringArray( _      &lt;br /&gt;&amp;#160; ByVal theMembershipCollection As MembershipUserCollection) As String()       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim usersInRole As New List(Of String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; For Each user As MembershipUser In theMembershipCollection       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; usersInRole.Add(user.UserName)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Next       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Return usersInRole.ToArray()       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This will iterate through the collection, and put the users in a format that we can return as an array. Next, we’ll add functionality for clicking on a letter. Add the following to the rptAlphabetRepeaterRoles_ItemCommand event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;gvUsersForRole.PageIndex = 0      &lt;br /&gt;Dim arg As String = e.CommandArgument.ToString()       &lt;br /&gt;      &lt;br /&gt;Dim users As MembershipUserCollection = Nothing       &lt;br /&gt;If arg.ToLower() = &amp;quot;all&amp;quot; Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; users = Membership.GetAllUsers()       &lt;br /&gt;Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; users = Membership.FindUsersByName(arg + &amp;quot;%&amp;quot;)       &lt;br /&gt;End If       &lt;br /&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;&lt;strike&gt;SetDataSource(ConvertMUCollToStringArray(users), _&amp;#160; &lt;br /&gt;&lt;/strike&gt;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/strong&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;&lt;strike&gt;ROLES_DATA_SOURCE)            &lt;br /&gt;BindGrid(gvUsersForRole, ROLES_DATA_SOURCE, True)&lt;/strike&gt;          &lt;br /&gt;SetDataSource(ConvertMUCollToStringArray(users), _           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; USERS_IN_ROLE_DATA_SOURCE)          &lt;br /&gt;BindGrid(gvUsersForRole, USERS_IN_ROLE_DATA_SOURCE, True)&lt;/font&gt;&lt;/strong&gt;      &lt;br /&gt;If gvUsersForRole.Rows.Count = 0 Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblNoUsersFoundRoles.Visible = True       &lt;br /&gt;End If&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;First, we’ll reset the PageIndex on our Gridview, and the pull the argument that was passed in (the letter that was clicked). Next, we’ll create an object to hold the the users found when searching for our argument, and then pull the appropriate subset of users. Next, we set our datasource (notice that in the process we convert our users object through our helper function to a string array), and then bind our GridView. Finally, we’ll check to see if we have an empty dataset and if so, display a message that no users were found.&lt;/p&gt;  &lt;p&gt;Finally, in relation to our search portion, we’ll hookup the search button for the text entry portion. Add the following to our btnSearchUsersForRoles_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Dim users As MembershipUserCollection = _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SearchForUsers(ddlSearchForUsersRole, txtSearchUsersForRoles)       &lt;br /&gt;SetDataSource(ConvertMUCollToStringArray(users), ROLES_DATA_SOURCE)       &lt;br /&gt;BindGrid(gvUsersForRole, ROLES_DATA_SOURCE, True)       &lt;br /&gt;If gvUsersForRole.Rows.Count = 0 Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblNoUsersFoundRoles.Visible = True       &lt;br /&gt;End If&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;When the user clicks the search button, we’ll retrieve a collection of MembershipUser objects, meeting our criteria. Then we’ll set our datasource, once again converting to string array, and then bind our GridView with the results. Finally, we’ll check for empty dataset, and display a message if no users are found.&lt;/p&gt;  &lt;p&gt;Next, let’s add functionality for the ‘User is in Role’ checkbox. When we check or uncheck it, it will update the database adding or removing the user from the role. In our front-end code, we specify that the checkbox’s onCheckChange event calls the ‘ChangeUserIsAssignedToRole’ subroutine. Define it as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Sub ChangeUserIsAssignedToRole(ByVal sender As Object, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal e As EventArgs)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim theCheckbox As CheckBox = CType(sender, CheckBox)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim theItem As GridViewRow = _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CType(theCheckbox.Parent.Parent, GridViewRow)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim theLabel As Label = _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CType(theItem.FindControl(&amp;quot;lblUsernameRole&amp;quot;), Label)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If theCheckbox.Checked = True Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Roles.AddUserToRole(theLabel.Text, _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblRoleToAddRemoveUsersTo.Text)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Roles.RemoveUserFromRole(theLabel.Text, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblRoleToAddRemoveUsersTo.Text)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;First, we retrieve checkbox that was clicked (it’s passed in as a parameter), and then use that to retrieve the GridViewRow containing the checkbox (the checkbox’s parent’s parent). From that we’ll get the username. If the checkbox is now checked, we’ll add the user to the role, if not, we’ll remove the user from the role.&lt;/p&gt;  &lt;p&gt;That finishes all the functionality for the ‘Assign Users’ link. Next, we’ll concentrate on the ‘Change Role Name’ functionality. First, we’ll need to create some front-end dialogs to support this functionality. We’ll need to create a confirmation dialog, and we’ll need to create a dialog that allows us to input the new name. We also need a dialog to confirm the name change. Add the following to your front-end code anywhere inside our pnlFormatEverything panel:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;%-- Change Role Name Dialog --%&amp;gt;      &lt;br /&gt;&amp;lt;asp:UpdatePanel id=&amp;quot;upnlChangeRoleName&amp;quot; runat=&amp;quot;server&amp;quot; ChildrenAsTriggers=&amp;quot;true&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ContentTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlChangeRoleName&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; style=&amp;quot;display: none;&amp;quot; CssClass=&amp;quot;modalPopup&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HorizontalAlign=”center”&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Enter a new role name.&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Table runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Current role name:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Left&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label runat=&amp;quot;server&amp;quot; ID=&amp;quot;lblCurrentRoleName&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;&amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; New role name:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Left&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TextBox ID=&amp;quot;txtNewEditRoleName&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:TextBoxWatermarkExtender ID=&amp;quot;tweNewRoleName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;txtNewEditRoleName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkText=&amp;quot;Enter new role name&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkCssClass=&amp;quot;watermarked&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;rfvNewRoleName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Display=&amp;quot;Dynamic&amp;quot; text=&amp;quot;*&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ControlToValidate=&amp;quot;txtNewEditRoleName&amp;quot;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationGroup=&amp;quot;ChangeRoleName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ErrorMessage=&amp;quot;You must enter a new role name.&amp;quot;&amp;#160; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell ColumnSpan=&amp;quot;3&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:ValidationSummary ID=&amp;quot;vsNewRoleName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; EnableClientScript=&amp;quot;true&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DisplayMode=&amp;quot;List&amp;quot; ShowSummary=&amp;quot;true&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationGroup=&amp;quot;ChangeRoleName&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Table&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkRenameRoleSave&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CausesValidation=&amp;quot;true&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Save&amp;quot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationGroup=&amp;quot;ChangeRoleName&amp;quot; /&amp;gt;&amp;amp;nbsp;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkRenameRoleCancel&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Cancel&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Panel&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button ID=&amp;quot;btnFakeShowMPEChangeRoleName&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; style=&amp;quot;display: none;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:ModalPopupExtender id=&amp;quot;mpeChangeRoleName&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;btnFakeShowMPEChangeRoleName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PopupControlID=&amp;quot;pnlChangeRoleName&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BackgroundCssClass=&amp;quot;modalBackground&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ContentTemplate&amp;gt;       &lt;br /&gt;&amp;lt;/asp:UpdatePanel&amp;gt;       &lt;br /&gt;      &lt;br /&gt;&amp;lt;%-- Role rename confirm dialog --%&amp;gt;       &lt;br /&gt;&amp;lt;asp:UpdatePanel ID=&amp;quot;upnlChangeRoleNameConfirm&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ContentTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlChangeRoleNameConfirm&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; style=&amp;quot;display:none;&amp;quot; CssClass=&amp;quot;modalPopup&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HorizontalAlign=&amp;quot;Center&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Literal ID=&amp;quot;lblRoleToRename&amp;quot; runat=&amp;quot;server&amp;quot; isible=&amp;quot;false&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Literal ID=&amp;quot;lblConfirmRoleRename&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button ID=&amp;quot;btnRoleRenameYes&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Yes&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button ID=&amp;quot;btnRoleRenameNo&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;No&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Panel&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button ID=&amp;quot;btnFakeShowMPERoleRenameConfirm&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; style=&amp;quot;display:none;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:ModalPopupExtender runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID=&amp;quot;mpeRoleRenameConfirm&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;btnFakeShowMPERoleRenameConfirm&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PopupControlID=&amp;quot;pnlChangeRoleNameConfirm&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BackgroundCssClass=&amp;quot;modalBackground&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ContentTemplate&amp;gt;       &lt;br /&gt;&amp;lt;/asp:UpdatePanel&amp;gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now, we just need to add the functionality. We’ll need to add another block to our RoleLinkButtonClicked event handler. Add the following If Then statement to the subroutine:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;If e.CommandName.Equals(&amp;quot;EditRoleName&amp;quot;) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblCurrentRoleName.Text = CStr(e.CommandArgument)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; mpeChangeRoleName.Show()       &lt;br /&gt;End If&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Basically, we’re just displaying our change role name dialog. We do populate a label in the dialog so that the administrator knows what role is being changed. Next, we need to add functionality to our ‘Save’ and ‘Cancel’ buttons. Add the following to our lnkRenameRoleSave_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;lblRoleToRename.Text = lblCurrentRoleName.Text      &lt;br /&gt;      &lt;br /&gt;lblConfirmRoleRename.Text = &amp;quot;Warning, if the role name you are changing is used in your code, renaming a role may break your code. Please proceed with caution!&amp;lt;/br&amp;gt;&amp;lt;br&amp;gt;Are you sure you want to rename '&amp;quot; &amp;amp; lblRoleToRename.Text &amp;amp; &amp;quot;' to '&amp;quot; &amp;amp; txtNewRoleName.Text &amp;amp; &amp;quot;'?&amp;quot;       &lt;br /&gt;      &lt;br /&gt;SetUI(SetUIModes.RenameRoleConfirm)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We store our role name so that we have it available when we click ‘Yes’, and set a long warning to the administrator letting them know that if they rename a role, they could possibly break their code. Renaming roles is another one of those features that is unsupported by Microsoft. In Microsoft’s defense, it really is a questionable practice though. If you have specified anything in your application calling the role by name, when you rename it here, it will no longer trigger the appropriate functionality in your application, thus breaking your code. (USE THIS FEATURE WISELY…) Add the following to our lnkRenameRoleCancel_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;txtNewEditRoleName.Text = String.Empty      &lt;br /&gt;lblCurrentRoleName.Text = String.Empty&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This just clears out anything hanging around when we cancel the dialog.&lt;/p&gt;  &lt;p&gt;Finally, we’ll want to hook up our ‘Yes’ and ‘No’ buttons on our confirmation dialog. We’ll start with ‘No’. Add the following to our btnRoleRenameNo_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;SetUI(SetUIModes.RenameRole)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We will just go back to the change role dialog if the administrator doesn’t confirm. Next, add the following to our btnRoleRenameYes_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Dim usersInRole As String() = Roles.GetUsersInRole(lblRoleToRename.Text)      &lt;br /&gt;Roles.CreateRole(txtNewEditRoleName.Text)       &lt;br /&gt;If usersInRole.Length &amp;gt; 0 Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Roles.AddUsersToRole(usersInRole, txtNewEditRoleName.Text)&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Roles.RemoveUsersFromRole(usersInRole, lblRoleToRename.Text)       &lt;br /&gt;End If       &lt;br /&gt;Roles.DeleteRole(lblRoleToRename.Text)       &lt;br /&gt;txtNewEditRoleName.Text = String.Empty       &lt;br /&gt;lblRoleToRename.Text = String.Empty       &lt;br /&gt;SetUI(SetUIModes.ManageAllRoles)       &lt;br /&gt;gvRoles.DataSource = Roles.GetAllRoles()       &lt;br /&gt;gvRoles.DataBind()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You’ll notice, that we can’t just rename the role, the functionality isn’t included in the Microsoft Role provider, so we have to work around it. What we’ll do, is retrieve the users in the role that we want to rename, we’ll check that string array that we retrieve, and if it has any elements, we know that there are users in the role. We’ll add these users to our new role (after we create it) and then remove those users from the old role, and then delete the old role (since we can’t delete a role with users in it). (That’s our work around, add all the users from our old role to the new role, remove them from the old role, and then delete the old role). Once we are done, we’ll clear our dialog and then close it. Finally, we’ll rebind our GridView so that it displays our new role name.&lt;/p&gt;  &lt;p&gt;**Author’s Note** – I found one more small problem, paging for the Role’s grids don’t work. Unfortunately in my development, I didn’t put more than one page worth of anything into my database (users or roles). Thus, I never checked to make sure my paging worked, I never needed to page. As a result, paging for both gvRoles and gvUsersForRole will return a JavaScript error. This is because we don’t handle their PageIndexChanging event handler. Since we’re using AJAX, the JavaScript will call the back-end, but cause an error because the event handler doesn’t exist. So to remedy this problem we’ll add the following lines to our gvRoles_PageIndexChanging event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;gvRoles.PageIndex = e.NewPageIndex      &lt;br /&gt;BindGrid(gvRoles, ROLES_DATA_SOURCE, False)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and the following to our gvUsersForRole_PageIndexChanging event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;UsersForRole.PageIndex = e.NewPageIndex      &lt;br /&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;&lt;strike&gt;BindGrid(gvUsersForRole, ROLES_DATA_SOURCE, False)           &lt;br /&gt;&lt;/strike&gt;BindGrid(gvUsersForRole, USERS_IN_ROLE_DATA_SOURCE, False)&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You’ll also notice that I made a little change in our lnkManageRoles_click event handler. To be able to use paging, we need to store our datasource, so rather than binding our gvRoles directly from our Roles provider (Roles.GetAllRoles()), we’ll set our DataSource and then use it later when we call our PageIndexChanging event handler.&lt;/p&gt;  &lt;p&gt;Now paging works. Funny what you find when you do some real testing…&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Epilogue &lt;/p&gt;  &lt;p&gt;And there we have it. The final pieces of our functionality. All we need to manage all aspects of our Roles. We can now Add, Delete, Rename, and assign/unassign users from our roles. &lt;/p&gt;  &lt;p&gt;Technically, we’re done with our control, we’ve done everything we need to do to successfully use it, however, I think that I’ll do one more post in this series offering some optional enhancements that I may someday use if I feel like it, but that may come in useful none the less.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx&amp;amp;;subject=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+6" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx&amp;amp;;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+6" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx&amp;amp;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+6" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx&amp;amp;;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+6" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx&amp;amp;;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+6&amp;amp;;top=1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2009/01/21/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-6.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://aspadvice.com/aggbug.aspx?PostID=50299" width="1" height="1"&gt;</description></item><item><title>A Better ASP.Net Member/Role Management Page Pt. 5</title><link>http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx</link><pubDate>Thu, 04 Dec 2008 07:37:21 GMT</pubDate><guid isPermaLink="false">e709ad4c-0c15-48eb-915e-c462c6e85445:49105</guid><dc:creator>Yougotiger</dc:creator><slash:comments>4</slash:comments><comments>http://aspadvice.com/blogs/net_discoveries/comments/49105.aspx</comments><wfw:commentRss>http://aspadvice.com/blogs/net_discoveries/commentrss.aspx?PostID=49105</wfw:commentRss><wfw:comment>http://aspadvice.com/blogs/net_discoveries/rsscomments.aspx?PostID=49105</wfw:comment><description>&lt;p class="MyHeadings"&gt;Prologue&lt;/p&gt;  &lt;p&gt;**Author Note – If you are bewildered by a line (perhaps two) that are red and bold, don’t they that they’re errors, they are corrections/additions. Please see the comments, after the article for comments regarding the highlighted line(s).**&lt;/p&gt;  &lt;p&gt;In previous posts we started creating “A Better ASP.Net Member/Role Management Page.” In &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/09/29/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-1.aspx"&gt;part 1&lt;/a&gt;, we set criteria, and in &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/10/07/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-2.aspx"&gt;part 2&lt;/a&gt;, &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/10/14/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-3.aspx"&gt;part 3&lt;/a&gt; and &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/11/06/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-4.aspx"&gt;part 4&lt;/a&gt; we created functionality to add, delete and edit users. We’ve finished nearly all the functionality for editing users with one exception, changing usernames. We’ll be addressing that in this post.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Problem&lt;/p&gt;  &lt;p&gt;Changing a username is functionality that isn’t included in the default Microsoft membership provider. The reason for this, in my understanding, is that changing usernames is considered somewhat of a security issue. Really,i don’t understand why it isn’t included, changing a username could be put together in such a way that it is reasonably secure, you know require passwords and or security questions etc. like practically everything else that you try to change using the membership provider does. Although the functionality isn’t included in the Microsoft provider, we can add the functionality on our own (and it’s actually relatively easy).&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Solution&lt;/p&gt;  &lt;p&gt;Unfortunately, this functionality will be the one part that we won’t be able to contain fully in our page, we’ll have to add a stored procedure to our database. Well, I guess we could put all our SQL stuff in a subroutine, but that’s leaves us with a security problem, accepting user in put and just inserting into a SQL statement and running it directly form our page leaves us open for SQL injection attack. The most secure thing would be to create a stored procedure in the database, and like I said that means that we don’t have a fully self contained page.&lt;/p&gt;  &lt;p&gt;To workaround this limitation, what we’ll do is add a property to the page so that we can indicate that we have created the stored procedure and we can change the username. This will turn on/off the ‘change username’ link on our page.&lt;/p&gt;  &lt;p&gt;Let’s start with the SQL stored procedure. If you’ve ever looked at a database that’s enabled for the ASP.net membership provider you will notice that enabling a database for ASP.Net membership provider adds a number of stored procedures. We’ll add another stored procedure and we’ll use the same naming convention. To add the stored procedure execute the following SQL code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;CREATE PROCEDURE aspnet_Membership_ChangeUsername      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @currentUsername nvarchar(255),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @newUsername nvarchar(255),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @results bit OUTPUT       &lt;br /&gt;AS       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; UPDATE aspnet_Users       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SET UserName = @newUsername,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LoweredUserName = LOWER(@newUsername)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WHERE LOWER(UserName) = LOWER(@currentUsername)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; set @results = @@ROWCOUNT&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The stored procedure here will take three parameters, one for each of the usernames, the new and the old, and one parameter to output the success of the operation. It will return 0 on failure and 1 on success (as one row was changed on success). The actual username data is actually only stored in one location, in the user table. Rather than using the username as the ID to link with all other tables, there’s a unique UserID in the user table that is used. Changing the username is easy, we have two places to change it in one table and it doesn’t take much.&lt;/p&gt;  &lt;p&gt;Once that’s done, we need to add the functionality to our page. We don’t have much to add to the front-end code, just the change username dialog and a new style. Add the following to your style section:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;.taken      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; color: Red;       &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and the following to your front end code. Place it at the end of the page, but before our closing tag for our pnlFormatEverything panel:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;%-- Change Username Dialog --%&amp;gt;      &lt;br /&gt;&amp;lt;asp:UpdatePanel id=&amp;quot;upnlChangeUsername&amp;quot; runat=&amp;quot;server&amp;quot; ChildrenAsTriggers=&amp;quot;true&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ContentTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlChangeUsername&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; style=&amp;quot;display: none;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text-align:center;&amp;quot; CssClass=&amp;quot;modalPopup&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;b&amp;gt;Enter a New Username&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Table runat=&amp;quot;server&amp;quot; ID=&amp;quot;tblChangeUsername&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Current Username:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Left&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblCurrentUsername&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;&amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Tablerow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; New Username:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Left&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TextBox ID=&amp;quot;txtNewUsername&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#ff0000"&gt;&lt;strong&gt;&amp;lt;div runat=&amp;quot;server&amp;quot; id=&amp;quot;divUserAvailablity&amp;quot;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; class=&amp;quot;taken&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/strong&gt;&lt;/font&gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:TextBoxWatermarkExtender       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID=&amp;quot;tbeNewUsername&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;txtNewUsername&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkText=&amp;quot;Enter New Username&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkCssClass=&amp;quot;watermarked&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/cc1:TextBoxWatermarkExtender&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:RequiredFieldValidator runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID=&amp;quot;rfvNewUsername&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ControlToValidate=&amp;quot;txtNewUsername&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Display=&amp;quot;Dynamic&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationGroup=&amp;quot;ChangeUsername&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ErrorMessage=&amp;quot;You must enter a new username&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;*&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Tablerow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell ColumnSpan=&amp;quot;3&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:ValidationSummary ID=&amp;quot;vsNewUsername&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationGroup=&amp;quot;ChangeUsername&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DisplayMode=&amp;quot;List&amp;quot; ShowSummary=&amp;quot;true&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EnableClientScript=&amp;quot;true&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Table&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkChangeUsernameSave&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Save&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CausesValidation=&amp;quot;true&amp;quot; ValidationGroup=&amp;quot;ChangeUsername&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkChangeUsernameCancel&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Cancel&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Panel&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button ID=&amp;quot;btnFakeShoeMPEChangeUsernameDialogButton&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; style=&amp;quot;display:none;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:ModalPopupExtender ID=&amp;quot;mpeChangeUsername&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;btnFakeShoeMPEChangeUsernameDialogButton&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PopupControlID=&amp;quot;pnlChangeUsername&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BackgroundCssClass=&amp;quot;modalBackground&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/cc1:ModalPopupExtender&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ContentTemplate&amp;gt;       &lt;br /&gt;&amp;lt;/asp:UpdatePanel&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Basically we’re just creating a label to put in the existing username, a textbox for the new username and then save and cancel buttons. We also add a div so that we can tell the user if the new username is already being used.&lt;/p&gt;  &lt;p&gt;Now let’s add the back end code. First, we’ll add another entry to our SetUI enumeration, and another case to our SetUI case statement. Add the following line to our enumeration:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;ChangeUsername&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and add the following case statement to our SetUI Case statement:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Case SetUIModes.ChangeUsername      &lt;br /&gt;&amp;#160;&amp;#160; mpeChangeUsername.Show()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Next, we’ll hook up the ‘Change Username’ LinkButton. It’s functionality is pretty easy. Add the following to the our lnkChangeUsername_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;lblCurrentUsername.Text = lblUsernameEdit.Text      &lt;br /&gt;SetUI(SetUIModes.ChangeUsername)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We set the current username and then show the dialog.&lt;/p&gt;  &lt;p&gt;We don’t need to do anything with the cancel button as it will function correctly without help, however we need to hook up the functionality for the Save button. We’ll want to do a little checking to see if the username is being used before we actually do any changing. We’ll want to display a message that it’s taken if it is. We’ll also want to make sure that the username was successfully changed in the database when we actually execute the SQL. Well add two helper functions, the first to check username availability. Add the following function:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Function CheckUsernameIsAvailable( _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal sUsernameToCheck As String) As Boolean       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If IsNothing(Membership.GetUser(sUsernameToCheck)) = False Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return True       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Basically, we receive the new username and then check to see if we can retrieve a MembershipUser object from the database. If we can, then the username is NOT available and we return false.&lt;/p&gt;  &lt;p&gt;We’ll also want to create a helper function to perform the actual database work, since our membership provider doesn’t do this for us. Add the following helper function (I apologize in advance for dividing of the lines in such a terrible manner…):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Function ChangeUsername(ByVal sCurrentUsername As String, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal sNewUsername As String, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Optional ByVal iOrdinalForConnectionString As Integer = 0) As Boolean&amp;#160; &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; Using cn As New SqlConnection( _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ConfigurationManager.ConnectionStrings( _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; iOrdinalForConnectionString).ConnectionString)&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim cmd As New SqlCommand _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&amp;quot;aspnet_Membership_ChangeUsername&amp;quot;, cn)&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.CommandType = Data.CommandType.StoredProcedure&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&amp;quot;@currentUsername&amp;quot;, Data.SqlDbType.NVarChar).Value _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; = sCurrentUsername&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&amp;quot;@newUsername&amp;quot;, Data.SqlDbType.NVarChar).Value _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; = sNewUsername&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add(&amp;quot;@Results&amp;quot;, Data.SqlDbType.Bit).Direction _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; = Data.ParameterDirection.Output&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#ff0000"&gt;&lt;strong&gt;&lt;strike&gt;cn.Open()&lt;/strike&gt;&lt;/strong&gt;&lt;/font&gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Try       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#ff0000"&gt;&lt;strong&gt;cn.Open()&lt;/strong&gt;&lt;/font&gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.ExecuteNonQuery()&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Catch ex As Exception&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return False&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Finally&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cn.Close()&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Try&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return cmd.Parameters(&amp;quot;@Results&amp;quot;).Value&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160; End Using       &lt;br /&gt;End Function&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This function is easily the least flexible in the entire object. Notice we pass in both the old and the new usernames. We also pass in an ordinal for the connectionString to use. Unfortunately we are unable to determine the connectionString currently being used in the membership provider, so we have to pass in the ordinal of the connection string we are using. In my case, I don’t even have a connectionString as I’m using the ASP.Net default sqlexpress database, so an ordinal of 0 works for me. You may need to play with what you pass in depending on your connectionstring setup. We use this connectionString to create a connection. With this connection, we create a command object, load it up with our parameters, including an output parameter. We then attempt to execute the stored procedure. If it fails we return false, otherwise we return the success/failure results from the actual database execution. You’ll notice that we use some SQL Data client objects so we’ll need to import the following namespace (or fully qualify all your SQL objects). Add the following import statement to the top of your document:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Imports System.Data.SqlClient&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;With our helper functions out of the way, we can now concentrate on our save routine. Add the following to your lnkChangeUsernameSave_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;If CheckUsernameIsAvailable(txtNewUsername.Text) = False Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; divUserAvailablity.InnerText = &amp;quot;Username taken, sorry.&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetUI(SetUIModes.ChangeUsername)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Exit Sub       &lt;br /&gt;End If       &lt;br /&gt;If ChangeUsername(lblCurrentUsername.Text, txtNewUsername.Text) = True Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetDataSource(Membership.GetAllUsers(), USERS_DATA_SOURCE)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; BindGrid(gvManageUsers, USERS_DATA_SOURCE, False)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblMessageDialog.Text = &amp;quot;Username successfully changed.&amp;quot;       &lt;br /&gt;Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblMessageDialog.Text = &amp;quot;Username change failed.&amp;quot;       &lt;br /&gt;End If       &lt;br /&gt;txtNewUsername.Text = String.Empty       &lt;br /&gt;divUserAvailablity.InnerText = String.Empty       &lt;br /&gt;SetUI(SetUIModes.MessageDialog)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;First we check to make sure the username is available. If it isn’t, then we’ll put up a message much like our validation letting the administrator know that it’s taken. We’ll make sure our change username dialog is still up and then exit the sub. If it’s valid, we attempt to perform the actual change. If the change is successful, we’ll refresh our data source, and then update our GridView with the new username information. Whether it fails or is successful, we’ll set the message dialog, and then when all is said and done, show the message. We’ll also reset our new username TextBox and our availability div so that they are both blank and ready to use next time.&lt;/p&gt;  &lt;p&gt;Ok, so we’ve got all our functionality working, but what if a user of our control didn’t put the stored procedure into the database? We’ll need to disable the functionality in that case. Actually, what we’ll do is disable the functionality be default, and then add it back in if the control’s user specifically enables it. We’ll add a property to our user control that will control the ‘Change username’ link so that the functionality to call the DB is only available if the control’s user specifically configures it to say that the DB has been setup. Add the following to define our property:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Enum ChangeUsernameSettings      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DbIsSetup       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DbIsNotSetup       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DisableLink       &lt;br /&gt;End Enum       &lt;br /&gt;      &lt;br /&gt;Private _ChangeUsernameFunctionality As ChangeUsernameSettings _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; = ChangeUsernameSettings.DbIsNotSetup       &lt;br /&gt;      &lt;br /&gt;Public Property ChangeUsernameFunctionality()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _ChangeUsernameFunctionality       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _ChangeUsernameFunctionality = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Here, we create a enumeration for our different settings. Next we create a private variable to hold our property’s current setting, and set it by default to be DbIsNotSetup. Finally we create our property.&lt;/p&gt;  &lt;p&gt;Now we’ll need to implement some things so that the settings are used. Add the following line to your SetupEditUser subroutine (anywhere will work):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;If _ChangeUsernameFunctionality = ChangeUsernameSettings.DisableLink _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Then lnkChangeUsername.Enabled = False&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If disableLink is selected, then we’ll disable it during our EditUser dialog setup. We could add a tooltip if desired, letting the administrator using the page what needs to be done to add the functionality. Next add the following to your lnkChangeUsername_Click event handler (apologies for the big block of text in the middle that has no link breaks (for readability)):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;If _ChangeUsernameFunctionality&amp;#160; =&amp;#160; _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ChangeUsernameSettings.DbIsNotSetup Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; lblMessageDialog.Text = _       &lt;br /&gt;&amp;quot;For this fundtion to be available, the following must be met: &amp;lt;br&amp;gt; 1. The database needs to have a stored procedure created for this functionality and &amp;lt;br&amp;gt; 2. the administrator must explicitly control to specify that the functinality is in the database.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt; Please see the documentation for more information.&amp;quot;       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetUI(SetUIModes.MessageDialog)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Exit Sub       &lt;br /&gt;End If&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If our page creator doesn’t specifically enable on this functionality, the administrator using our control will receive a message letting them know what needs to happen for the functionality to be enabled. And of course, if we set the property to DbIsSetup, then we’ll have our functionality back.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Epilogue &lt;/p&gt;  &lt;p&gt;Ugh… as in ugly. Truly, this isn’t the cleanest portion of our functionality, we are completely disregarding just about every one of our rules about keeping this control self contained and trying to make it useful across the board. But, in our defense, we’re making up for functionality limitations built into the the .Net framework (or is it limitations NOT built into…?). We could of course extend, or rewrite our membership provider, but I choose not to do it that way.&lt;/p&gt;  &lt;p&gt;This should fulfill all the requirements we had previously for our membership portion of our management page. Now we just need to work on the roles administration portion. That will be the subject of the next post(s).&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx&amp;amp;;subject=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+5" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx&amp;amp;;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+5" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx&amp;amp;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+5" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx&amp;amp;;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+5" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx&amp;amp;;title=A+Better+ASP.Net+Member%2fRole+Management+Page+Pt.+5&amp;amp;;top=1" target="_blank" title = "Post http://aspadvice.com/blogs/net_discoveries/archive/2008/12/04/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-5.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://aspadvice.com/aggbug.aspx?PostID=49105" width="1" height="1"&gt;</description></item><item><title>A Better ASP.Net Member/Role Management Page Pt. 4</title><link>http://aspadvice.com/blogs/net_discoveries/archive/2008/11/06/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-4.aspx</link><pubDate>Thu, 06 Nov 2008 21:33:13 GMT</pubDate><guid isPermaLink="false">e709ad4c-0c15-48eb-915e-c462c6e85445:48045</guid><dc:creator>Yougotiger</dc:creator><slash:comments>4</slash:comments><comments>http://aspadvice.com/blogs/net_discoveries/comments/48045.aspx</comments><wfw:commentRss>http://aspadvice.com/blogs/net_discoveries/commentrss.aspx?PostID=48045</wfw:commentRss><wfw:comment>http://aspadvice.com/blogs/net_discoveries/rsscomments.aspx?PostID=48045</wfw:comment><description>&lt;p class="MyHeadings"&gt;Prologue&lt;/p&gt;  &lt;p&gt;**Author Note &amp;#8211; If you are bewildered by a line (perhaps two) that are red and bold, don&amp;#8217;t they that they&amp;#8217;re errors, they are corrections/additions. Please see the comments, after the article for comments regarding the highlighted line(s).**&lt;/p&gt;  &lt;p&gt;Previously, we started work on &amp;#8220;A better ASP.Net Member/Role Management Page&amp;#8221;. So far, we looked at requirements in &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/09/29/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-1.aspx" target="_blank"&gt;Part 1&lt;/a&gt;, we then added functionality in &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/10/07/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-2.aspx" target="_blank"&gt;Part 2&lt;/a&gt; to display, filter and search existing user and finally, in &lt;a href="http://aspadvice.com/blogs/net_discoveries/archive/2008/10/14/A-Better-ASP.Net-Member_2F00_Role-Management-Page-Pt.-3.aspx" target="_blank"&gt;Part 3&lt;/a&gt;, we added functionality to create and delete users from the system. In this post, we&amp;#8217;ll be adding functionality to edit a user&amp;#8217;s account information.&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Problem&lt;/p&gt;  &lt;p&gt;In this post, we&amp;#8217;ll be creating the functionality we need to edit users. This is perhaps one of the most &lt;strike&gt;convoluted&lt;/strike&gt; lengthy parts of our series. We&amp;#8217;ll run into a number of places where the functionality isn&amp;#8217;t as simple as it seems or that we have limits based on how we&amp;#8217;ve configured our provider. Once we&amp;#8217;re finished with this post, we should have completed all of our requirements to complete #3 on our criteria list, with the exception of renaming (which will be addressing in the next post).&lt;/p&gt;  &lt;p class="MyHeadings"&gt;Solution&lt;/p&gt;  &lt;p&gt;Let's get started by creating all the front end markup for our Edit User dialog. We&amp;#8217;re going to introduce a lot of functionality in this post, and this markup will encapsulate most of it. The front-end code is kind of unwieldy, but here it is. I&amp;#8217;ll point out a couple of noteworthy items after the listing. Add the following after your last section, but before the closing tag for our formatEverything panel:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;%-- Edit User Dialog &amp;#8211;%&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;asp:UpdatePanel ID=&amp;quot;upnlEditUser&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ChildrenAsTriggers=&amp;quot;true&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ContentTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlEditUser&amp;quot; runat=&amp;quot;server&amp;quot; CssClass=&amp;quot;modalPopup&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; style=&amp;quot;display:none;&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Table runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell Width=&amp;quot;75%&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Table runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell ColumnSpan=&amp;quot;3&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;b&amp;gt;Edit User Details:&amp;lt;/b&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Username:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblUsernameEdit&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkChangeUsername&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; text=&amp;quot;Change Username&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Email:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TextBox ID=&amp;quot;txtEmail&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:TextBoxWatermarkExtender ID=&amp;quot;tweEmail&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; TargetControlID=&amp;quot;txtEmail&amp;#8221;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkCssClass=&amp;quot;watermarked&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkText=&amp;quot;Enter eMail&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/cc1:TextBoxWatermarkExtender&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:RegularExpressionValidator ID=&amp;quot;revEmail&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; ErrorMessage=&amp;quot;eMail not valid.&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ControlToValidate=&amp;quot;txtEmail&amp;quot; Display=&amp;quot;Dynamic&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationExpression=&amp;quot;\S+@\S+\.\S+&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Description:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TextBox ID=&amp;quot;txtDescription&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:TextBoxWatermarkExtender ID=&amp;quot;tweDescription&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;txtDescription&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkCssClass=&amp;quot;watermarked&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WatermarkText=&amp;quot;Enter description&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/cc1:TextBoxWatermarkExtender&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkResetPassword&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Reset Password&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Password:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblPassword&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;********&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkChangePassword&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Change Password&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Security Question:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblSecurityQuestion&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;&amp;quot; /&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkChangeSecurityQuestion&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Change Security Q/A&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Active User:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:CheckBox ID=&amp;quot;chkActiveUser&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;&amp;quot; Checked=&amp;quot;true&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;&amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Table&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;b&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblEditUserSelectRoles&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;#8221;Roles&amp;#8221; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/b&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Label ID=&amp;quot;lblEditAddUserToRole&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; Text=&amp;quot;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Repeater ID=&amp;quot;rptEditUserRoles&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:CheckBox ID=&amp;quot;chkRole&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;&amp;lt;%# Container.DataItem.ToString() %&amp;gt;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;br /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ItemTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Repeater&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell ColumnSpan=&amp;quot;2&amp;quot; HorizontalAlign=&amp;quot;Center&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkEditUserSave&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Save&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;amp;nbsp;&amp;amp;nbsp;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:LinkButton ID=&amp;quot;lnkEditUserCancel&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;Cancel&amp;quot; CausesValidation=&amp;#8221;False&amp;#8221; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Table&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:Panel&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Button ID=&amp;quot;btnFakeMPEEditUser&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; style=&amp;quot;display:none;&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;cc1:ModalPopupExtender ID=&amp;quot;mpeEditUser&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TargetControlID=&amp;quot;btnFakeMPEEditUser&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PopupControlID=&amp;quot;pnlEditUser&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BackgroundCssClass=&amp;quot;modalBackground&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/cc1:ModalPopupExtender&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;/ContentTemplate&amp;gt;       &lt;br /&gt;&amp;lt;/asp:UpdatePanel&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I&amp;#8217;m going against my anti-table-as-layout leanings again, and doubling up on that breach of protocol by nesting tables. In our code, we create a two row table, in the first row, we add almost everything except the buttons that will save or cancel. In the second row we add the save and cancel buttons. The first row has 2 cells one that holds a table with all the user information, and another with the role information. You&amp;#8217;ll notice that we have a couple of WatermarkExtenders for some of the text boxes.&lt;/p&gt;  &lt;p&gt;We also have one minor change to our cancel button over other&amp;#8217;s we&amp;#8217;ve used. You&amp;#8217;ll notice that we add CausesValidation=&amp;#8221;false&amp;#8221;. This will allow our button to close the dialog even if the entries in our form are not valid (otherwise we&amp;#8217;d have to get everything valid before we can even cancel).&lt;/p&gt;  &lt;p&gt;You&amp;#8217;ll also notice that we have a number of items that we&amp;#8217;ll link to yet other dialogs that provide the actual functionality (i.e. &amp;#8216;change password&amp;#8217;, &amp;#8216;change username&amp;#8217; and &amp;#8216;change security Q/A&amp;#8217;). These are a little more tricky to implement. For this reason, the actual functionality for these will not be directly effected by the &amp;#8216;Edit User&amp;#8217; dialog, rather they will work semi-independently of the dialog (i.e. they will be available from the &amp;#8216;Edit User&amp;#8217; dialog, but will not function based on clicking save/cancel on the &amp;#8216;Edit User&amp;#8217; dialog).&lt;/p&gt;  &lt;p&gt;With the front-end markup code finished, we&amp;#8217;re ready to get started on the back-end coding. Flip over to your code behind and let&amp;#8217;s get started. First we&amp;#8217;ll want to hookup our &amp;#8216;Edit User&amp;#8217; link to open our new dialog. If you remember, our Delete User link&amp;#8217;s event handler was the GridUsersClick subroutine. We&amp;#8217;ll need to add another if statement to our GridUsersClick event handler to catch the &amp;#8216;Edit User&amp;#8217; click. Add the following to your GridUsersClick subroutine, it doesn&amp;#8217;t matter if it is before or after the DeleteUser&amp;#8217;s if statement:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;If e.CommandName.Equals(&amp;quot;EditUser&amp;quot;) Then      &lt;br /&gt;&amp;#160;&amp;#160; SetupEditUser(e.CommandArgument)       &lt;br /&gt;&amp;#160;&amp;#160; SetUI(SetUIModes.EditUser)       &lt;br /&gt;End If&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We&amp;#8217;ll call a helper function to do a number of little things that it takes to populate our &amp;#8216;Edit User&amp;#8217; dialog. We are also passing the CommandArgument from the GridUsersClick to the routine, this will pass our username over to the setup routine so we know which user&amp;#8217;s information to pull. Create our SetupEditUser subroutine as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Sub SetupEditUser(ByVal sUsername As String)      &lt;br /&gt;&amp;#160;&amp;#160; lblUsernameEdit.Text = sUsername       &lt;br /&gt;&amp;#160;&amp;#160; Dim theUser As MembershipUser = Membership.GetUser(sUsername)       &lt;br /&gt;&amp;#160;&amp;#160; If IsNothing(theUser) Then Exit Sub       &lt;br /&gt;&amp;#160;&amp;#160; txtEmail.Text = theUser.Email       &lt;br /&gt;&amp;#160;&amp;#160; txtDescription.Text = theUser.Comment       &lt;br /&gt;&amp;#160;&amp;#160; chkActiveUser.Checked = theUser.IsApproved       &lt;br /&gt;&amp;#160;&amp;#160; lblSecurityQuestion.Text = theUser.PasswordQuestion       &lt;br /&gt;&amp;#160;&amp;#160; &lt;font color="#ff0000"&gt;&lt;strong&gt;SetDataSource(Roles.GetAllRoles, ROLES_DATA_SOURCE)          &lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;&amp;#160;&amp;#160; BindRepeater(rptEditUserRoles, ROLES_DATA_SOURCE)       &lt;br /&gt;&amp;#160;&amp;#160; SetupEditUserRoles(sUsername)&amp;#160; &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;First we grab the username and use it to retrieve the membership information for the user. The object that is returned has all the user&amp;#8217;s accessible information. If a valid object is returned, then we&amp;#8217;ll process the remainder of the routine. We pull each piece of information and display it. Then we bind the repeater for Roles with all the roles, and call another helper function SetupEditUserRoles. We&amp;#8217;ll use this to iterate through our repeater items and mark the roles that our user is currently assigned to. Finally we SetUI so that our &amp;#8216;Edit User&amp;#8217; dialog will appear. To make this helper routine function we need to add a couple things. First, let&amp;#8217;s add an entry to the SetUIModes Enumeration for &amp;#8216;EditUser&amp;#8217; and add the following case to our SetUI subroutine:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Case SetUIModes.EditUser      &lt;br /&gt;&amp;#160;&amp;#160; mpeEditUser.Show()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We also need to create our SetupEditUserRoles helper function so let&amp;#8217;s define it as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Sub SetupEditUserRoles(ByVal sUserName As String)      &lt;br /&gt;&amp;#160;&amp;#160; If rptEditUserRoles.Items.Count &amp;gt; 0 Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblEditAddUserToRole.Text = &amp;quot;Select Roles for user:&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For Each theItem As RepeaterItem In rptEditUserRoles.Items       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim chkRole As CheckBox = _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CType(theItem.FindControl(&amp;quot;chkRole&amp;quot;), CheckBox)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; chkRole.Checked = Roles.IsUserInRole(sUserName, chkRole.Text)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Next       &lt;br /&gt;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lblEditAddUserToRole.Text = &amp;quot;No roles defined.&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160; End If       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If our repeater has any items, then we&amp;#8217;ll add administrator directions to our &amp;#8216;Edit User&amp;#8217; dialog, and then iterate through each of the items in the repeater. We pull out the checkbox from the repeater&amp;#8217;s item and if see if the user is in the role associated with the checkbox. If they are, then we&amp;#8217;ll mark it checked. If there are not any roles, we&amp;#8217;ll also notify the administrator of such.&lt;/p&gt;  &lt;p&gt;Running your application at this point should allow you to select &amp;#8216;Edit User&amp;#8217; and get all the details about our user. If we have roles, they&amp;#8217;ll show up and if we have any assigned to the user, they&amp;#8217;ll be indicated as such. Now we need to hookup our &amp;#8216;Save&amp;#8217; button so that our changes are saved. (&amp;#8216;Cancel&amp;#8217; already automatically closes the dialog without saving). Add the following within our lnkEditUserSave_Click event handler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;If Not Page.IsValid() Then Return      &lt;br /&gt;Dim sUserName As String = lblUsernameEdit.Text       &lt;br /&gt;Try       &lt;br /&gt;&amp;#160;&amp;#160; Dim theEditedUser As MembershipUser = _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Membership.GetUser(sUserName)       &lt;br /&gt;&amp;#160;&amp;#160; theEditedUser.Email = txtEmail.Text       &lt;br /&gt;&amp;#160;&amp;#160; theEditedUser.Comment = txtDescription.Text       &lt;br /&gt;&amp;#160;&amp;#160; theEditedUser.IsApproved = chkActiveUser.Checked       &lt;br /&gt;&amp;#160;&amp;#160; Membership.UpdateUser(theEditedUser)       &lt;br /&gt;&amp;#160;&amp;#160; UpdateRoleMembership(rptEditUserRoles, sUserName)       &lt;br /&gt;Catch ex As Exception       &lt;br /&gt;&amp;#160;&amp;#160; lblMessageDialog.Text = &amp;quot;Error updating user and/or roles.&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160; SetUI(SetUIModes.MessageDialog)       &lt;br /&gt;&amp;#160;&amp;#160; Return       &lt;br /&gt;End Try&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;First we check if the page is valid (our validation controls will set this). If it isn&amp;#8217;t we&amp;#8217;ll exit, if it is we&amp;#8217;ll retrieve the username and use that to retrieve their MembershipUser object. From there we&amp;#8217;ll update the pieces of the User&amp;#8217;s information and then save the changes to the database. Finally, we update the role membership. We already created the helper subroutine to assign roles, so it should perform without any trouble. We wrap this in a try catch block so that if it fails we can notify the administrator that update failed. You may also notice that if update fails, we reuse the dialog that we created earlier to notify the administrator.&lt;/p&gt;  &lt;p&gt;Now that we&amp;#8217;ve saved the user&amp;#8217;s new information we need to update our GridView&amp;#8217;s datasource (and thus the GridView). We&amp;#8217;ll also notify our administrator that the changes were successful. Add the following to our lnkEditUserSave_Click event handler. Below our End Try statement:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;SetDataSource(Membership.GetAllUsers(), USERS_DATA_SOURCE)      &lt;br /&gt;BindGrid(gvManageUsers, USERS_DATA_SOURCE, True)       &lt;br /&gt;lblMessageDialog.Text = &amp;quot;You have successfully updated the user &amp;lt;b&amp;gt;&amp;quot; _       &lt;br /&gt;&amp;#160;&amp;#160; &amp;amp; sUserName &amp;amp; &amp;quot;&amp;lt;/b&amp;gt;.&amp;quot;       &lt;br /&gt;SetUI(SetUIModes.MessageDialog)       &lt;br /&gt;ResetEditUserDialog()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Here we reset our data source and then rebind our GridView. We set our message dialog and then show it. Finally we call a new helper subroutine, ResetEditUserDialog. This will clear out all the information that we put into our &amp;#8216;Edit User&amp;#8217; dialog. We can also call this when we click the cancel button if desired. This just makes sure that we don&amp;#8217;t have any stray information hanging around. Create the new helper subroutine as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Private Sub ResetEditUserDialog()      &lt;br /&gt;&amp;#160;&amp;#160; lblUsernameEdit.Text = String.Empty       &lt;br /&gt;&amp;#160;&amp;#160; txtDescription.Text = String.Empty       &lt;br /&gt;&amp;#160;&amp;#160; txtEmail.Text = String.Empty       &lt;br /&gt;&amp;#160;&amp;#160; lblSecurityQuestion.Text = String.Empty       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Really all we are doing is flushing out all the data in our dialog box. Now if you run your application and edit a user&amp;#8217;s information, we&amp;#8217;ll be able to successfully change and update the user&amp;#8217;s information.&lt;/p&gt;  &lt;p&gt;You may have noticed, but we still have a checkbox in the main GridView that we haven&amp;#8217;t wired up with anything but a stub. (the checkbox in front of the user&amp;#8217;s name). We can wire that up pretty easily. If you remember back, to the gridUsersClick portion, we&amp;#8217;ll need to define some parameters to receive information from the actual event (since currently our stub doesn&amp;#8217;t have them). From there we&amp;#8217;ll be able to work our magic. Modify the ChangeUserIsApproved stub as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Public Sub ChangeUserIsApproved(ByVal sender As Object, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal e As EventArgs)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;With these parameters, we can then access the properties that we need to change the user&amp;#8217;s approved status. Add the following as the body of your subroutine and we&amp;#8217;ll be good to go there:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;Dim theCheckbox As CheckBox = CType(sender, CheckBox)      &lt;br /&gt;Dim theItemRow As GridViewRow = CType(theCheckbox.Parent.Parent, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GridViewRow)       &lt;br /&gt;Dim theUserNameLabel As Label = _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CType(theItemRow.FindControl(&amp;quot;lblUsername&amp;quot;), Label)       &lt;br /&gt;Dim sUserName As String = theUserNameLabel.Text       &lt;br /&gt;Dim theUser As MembershipUser = _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Membership.GetUser(sUserName)       &lt;br /&gt;theUser.IsApproved = theCheckbox.Checked       &lt;br /&gt;Membership.UpdateUser(theUser)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;First we get the checkbox. Then we retrieve the GridViewRow containing the checkbox so that we can get the user&amp;#8217;s name. Finally we pull the label with the username from the GridViewRow and use that to retrieve the user from the Membership database. We change the user&amp;#8217;s IsApproved status and then the update the user.&lt;/p&gt;  &lt;p&gt;That leaves us with 4 LinkButtons on this page that we haven&amp;#8217;t yet addressed, &amp;#8216;Change Username&amp;#8217;, &amp;#8216;Reset Password&amp;#8217;, &amp;#8216;Change Password&amp;#8217; and &amp;#8216;Change Security Q/A&amp;#8217;. I saved these till last because your ability as an administrator to change/reset a user&amp;#8217;s password and security Q/A depends on how the Membership provider is configured.&lt;/p&gt;  &lt;p&gt;If you aren&amp;#8217;t familiar with the setup of membership providers in ASP.Net, I found an &lt;a href="http://mishler.net/2006/04/18/AspNetMembershipPasswordAdministration.aspx" target="_blank"&gt;excellent article&lt;/a&gt; that covers the provider settings and how they affect what you are allowed to do with passwords. Basically if we have set our provider up as the default (HASHED), then we don&amp;#8217;t have the option as administrators to &lt;u&gt;change&lt;/u&gt; the user&amp;#8217;s password, we can only &lt;u&gt;reset&lt;/u&gt; it. Also, even if we set our password as encrypted, then we&amp;#8217;ll not be able to change the user&amp;#8217;s password if our provider sets requiresQuestionAndAnswer to true, because we&amp;#8217;d have to have the user&amp;#8217;s security answer. &lt;/p&gt;  &lt;p&gt;The point is this, if we want to have the ability as an administrator to change the user&amp;#8217;s password, we&amp;#8217;ll either need to have the user&amp;#8217;s password and/or security question or configure our provider in such a way that we can retrieve the password. Here&amp;#8217;s the rub, we may not want to configure our provider that way for the users, however it may be appropriate for the administrator. One suggestion I found in my searching revolves around having 2 Membership providers and then using one for the users and one for the administrator. The two providers would both go to the same Membership database, but the difference would be in how you setup your provider details (such as enablePasswordRetrieval etc).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://aspadvice.com/photos/images_to_go_with_what_ive_learned/images/47527/original.aspx" target="_blank"&gt;&lt;img style="display:inline;margin-left:0px;margin-right:0px;" height="133" src="http://aspadvice.com/photos/images_to_go_with_what_ive_learned/images/47527/original.aspx" width="100" align="right" /&gt;&lt;/a&gt;In our case, what we&amp;#8217;ll do is examine the provider being used and determine if it meets the requirements necessary to allow us to perform the functions we&amp;#8217;d like, if not then we&amp;#8217;ll disable the feature. You may decide to try changing your membership provider around a little to test it in each of the scenarios. We&amp;#8217;ll use the flowchart on the right to determine what options we present to the administrator.&lt;/p&gt;  &lt;p&gt;We&amp;#8217;ll want to enable or disable the links on our &amp;#8216;Edit User&amp;#8217; dialog before it is shown, based on the provider&amp;#8217;s settings. While we could do this in the page_load, we&amp;#8217;ll create a subroutine that has all our functionality in it and call that subroutine from our editUserClick subroutine. Define our helper subroutine as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Private Const FUNCTIONALITY_NOT_ENABLED As String = _          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Provider not configured to allow this function.&amp;quot;           &lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;      &lt;br /&gt;Public Sub SetupEditPasswordLinks()       &lt;br /&gt;&amp;#160;&amp;#160; Dim bResetEnabled As Boolean = Membership.Provider.EnablePasswordReset       &lt;br /&gt;&amp;#160;&amp;#160; Dim bRetrievalEnabled As Boolean = Membership.Provider.EnablePasswordRetrieval       &lt;br /&gt;&amp;#160;&amp;#160; Dim bQnARequired As Boolean = Membership.Provider.RequiresQuestionAndAnswer       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160; If Membership.Provider.PasswordFormat = MembershipPasswordFormat.Hashed Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkChangePassword.Enabled = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkChangePassword.ToolTip = FUNCTIONALITY_NOT_ENABLED       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkChangeSecurityQuestion.Enabled = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkChangeSecurityQuestion.ToolTip = FUNCTIONALITY_NOT_ENABLED       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If bResetEnabled = False OrElse _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (bResetEnabled = True AndAlso bQnARequired = True) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkResetPassword.Enabled = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkResetPassword.ToolTip = FUNCTIONALITY_NOT_ENABLED       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If bRetrievalEnabled = False OrElse _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (bRetrievalEnabled = True AndAlso bQnARequired = True) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkChangePassword.Enabled = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkChangePassword.ToolTip = FUNCTIONALITY_NOT_ENABLED       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If bResetEnabled = False OrElse _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (bResetEnabled = True AndAlso bQnARequired = True) Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkResetPassword.Enabled = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkResetPassword.ToolTip = FUNCTIONALITY_NOT_ENABLED       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If bRetrievalEnabled = False Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkChangeSecurityQuestion.Enabled = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkChangeSecurityQuestion.ToolTip = FUNCTIONALITY_NOT_ENABLED       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160; If bRetrievalEnabled = False Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkChangeSecurityQuestion.Enabled = False       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lnkChangeSecurityQuestion.ToolTip = FUNCTIONALITY_NOT_ENABLED       &lt;br /&gt;&amp;#160;&amp;#160; End If       &lt;br /&gt;End Sub&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In this subroutine, we run through the scenarios in our flowchart and enable/disable our links for changing things dependant on our provider&amp;#8217;s settings. We also add an if statement to enable/disable our Change Security Q/A link if password retrieval is not enabled (as the password needs to be passed to the method to perform the change). Now we just need to call our helper subroutine. Add the following line to our gridUsersClick subroutine, just after the SetupEditUser call:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;SetupEditPasswordLinks()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You should now have your links enabled or disabled as appropriate to your provider configuration. Now we just need to make all the links functional. First, we&amp;#8217;ll need to create dialog boxes that allow us to enter the information for each of our functions. Add the following to our front-end code, following our last section, but before our formatEverything panel end tag:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="CodeSnippet"&gt;&amp;lt;%-- Change Password Dialog --%&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:UpdatePanel ID=&amp;quot;upnlChangePassword&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ChildrenAsTriggers=&amp;quot;true&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ContentTemplate&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;pnlChangePassword&amp;quot; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Style=&amp;quot;display: none&amp;quot; CssClass=&amp;quot;modalPopup&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Table runat=&amp;quot;server&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; New Password:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Left&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TextBox ID=&amp;quot;txtNewPassword&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; TextMode=&amp;quot;Password&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:RequiredFieldValidator ID=&amp;quot;rfvNewPassword&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; ControlToValidate=&amp;quot;txtNewPassword&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;*&amp;quot; Display=&amp;quot;Dynamic&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ErrorMessage=&amp;quot;New password cannot be blank.&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationGroup=&amp;quot;ChangePassword&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableRow&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Right&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Confirm Password:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell HorizontalAlign=&amp;quot;Left&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TextBox ID=&amp;quot;txtConfirmNewPassword&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot; TextMode=&amp;quot;Password&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:TableCell&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:CompareValidator ID=&amp;quot;cvConfirmPassword&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; runat=&amp;quot;server&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ControlToValidate=&amp;quot;txtConfirmNewPassword&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ControlToCompare=&amp;quot;txtNewPassword&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationGroup=&amp;quot;Ch