Archives

Archives / 2005 / December
  • ASP.NET 2.0 Profile Feature

    K. Scott Allen recently published a good post on the new ASP.NET 2.0 Profile system.  The profile system provides an easy way to store and retrieve properties about users on your sites -- both logged-in and anonymous.  It can save you time and effort in providing a richer personalized experience for people using your site.

  • Making a List, Checking it Twice (Cool Ajax Sample App with ASP.NET 2.0 and Atlas)

    In case you haven’t checked out the new Atlas preview release yet (which given that it shipped a few days ago and almost everyone is on vacation this week is very likely), you might want to consider finding some time to-do so when you get a chance and are back online.  It makes common Ajax-style scenarios a breeze to build, and really makes programming a lot of fun. 

     

    I played around using the Atlas drop with ASP.NET 2.0 a few days ago on a plane ride to the east-coast, and put together a simple task/to-do list application that shows off one of the new features that comes with it (specifically the new <atlas:updatepanel> server control that allows you to use any shipping ASP.NET server control and get incremental Ajax-style updates in your ASP.NET 2.0 application).

     

    You can download the full source-code to the application here.  Feel free to re-use/modify/re-ship it however you want.

     

    Basically, this simple sample I built provides a basic interface to create/manage/delete lists, and then items within those lists.  What is neat is that all of the inserts, updates, deletes, sorts, and paging operations within the application are done in an Ajax way (where only the list is updated in the browser – which makes the app feel really snappy and alive).  What is really cool is the fact that I was able to enable this without having to write any javascript, or learn/use any new data or input controls (I used only the built-in textbox, dropdownlist, button, gridview, repeater and objectdatasource controls in the sample – together with the new <asp:updatepanel> control which is conceptually pretty simple to understand).  I wrote ~40 lines of code to enable all the screenshots below (I could have easily done it in less than half of that – but I wanted to show off some fancier data transformations in the lists as well as enable RSS) – and I was able to build all of the core app functionality from scratch in less than 15 minutes (including creating the database, the data tier, and the UI code). 

     

    I’ll walkthrough how this all works after the sceenshots below – although obviously the best way to learn about it yourself is to download the sample and run it on your local system (note: if you have the free Visual Web Developer Express tool installed and SQL Express active, then you should be able to just copy the above .zip file to your local hard-drive, expand it, open the web-site and hit run).  Note: I used CSS for all style information, and I’ve tested the markup output from the sample and it should be XHTML compliant.

     

    Quick Tour of the Application

     

    Basically, this to-do list application provides a simple Ajax-enabled interface to manage lists of items (note: the screenshots are done with FireFox – but obviously it works with IE as well): 

     

     

    In addition to adding lists (which are done using an Ajax model – no refresh of the entire page), it also provides per-row editing of the values (also done in an Ajaxish way):

     

     

    As well as sorting (note: also done in an Ajaxish way with no full page refresh) by any of the columns (just click on a column heading to set the sort-order):

     

      

    Automatic paging support is enabled when you have more than 10 lists in your current filter (note: also done in an Ajaxish way):

     

     

    In addition to adding/editing/sorting/paging/deleting lists, you can also drill into list items and add individual sub-items (just click the “view active items” link to drill into this):

     

     

    Note that the number of active items is shown for each list in the far-right of the list manager screen (I also added code to disable the “delete” button on a list if there is 1 or more active items in the list):

     

     

    When you are done with a list (and presumably its items), you can edit the list and checkbox it as being “done”.  This will remove the list from the “active” filter and hide it from the default view.  You can still go in and see it by changing the top-filter drop-down list to “done” (also done in an Ajaxish way):

     

     

    Lastly, I also added support for viewing your current task-list using RSS.  Just click the “subscribe to your lists” link and you’ll see an RSS XML view of the data.

     

     

    You can then add a subscription to this RSS feed in your favorite RSS reader.  You will then be able to easily track your current to-do list, and even see the active items that are in it (every time you refresh your RSS feeds, it will automatically update your to-do list with the latest information:

     

     

    A little about what the sample code

     

    Use this link to download all of the source for the sample (this .zip file also includes an atlas install – so you should just be able to download it with a vanilla Visual Web Developer or VS 2005 install and hit run to launch it).  Note that I wrote this on a plane with a screaming kid behind me – so please be a little forgiving of the imperfections you find (and I am sure there are some). 

     

    Here is what it looks like in either the free Visual Web Developer IDE or in VS 2005:

     

     

    Note that it contains three .aspx pages – MyList.aspx, Items.aspx, and RSS.aspx.  MyList.aspx and Items.aspx are both based on a common master-page (Site.Master) that provides common layout information.  All style information is stored in the .css file. 

     

    The data for the application is stored within the Tasks.mdf file (which is a SQL Express file).  I then also created a set of strongly-typed dataset table adapters for the two tables I used within the database (these table adapters are declaratively defined within the Lists.xsd file). 

     

    As you can see above, both MyList.aspx and Items.aspx are fully supported in the WYSIWYG designer mode.  Here is the full code-listing for what the MyList.aspx code-behind file looks like (note: this code-behind is the largest of the three files):

     

     

    Note that the first method is the event handler action for the “add” button gets clicked.  It creates a new List in the database.  The next three methods are formatting methods I use during data-binding to perform some fancier data-transforms (for example: I store the priority of lists as an integer in the database as opposed to a string for better sorting semantics, but want a nice drop-down list and text value displayed in the browser, etc).  If I wanted a quick and dirty bare-bones list editing system, I could have just skipped doing these.  I’m then using a declarative ObjectDataSource binding (a new ASP.NET 2.0 feature) to-do update and delete data semantics with the List adapter as well. 

     

    How you’d build something like this from scratch

     

    If you want to build something like the above sample from scratch yourself, you’d want to follow these steps below:

     

    1) Create a new web-site using the free Visual Web Developer Tool and optionally the December Atlas Site Template .VSI file:

     

     

    2) After deleting the default Eula, Readme and Default.aspx files, you’ll be left with a solution that looks like this (note: the Atlas binary is added to your \bin directory by default, along with both debug and release versions of the Atlas .js files)

     

     

    3) Create a new SQL Express database.  To-do this, just select “Add New Item” and choose the “SQL Database” item and name it:

     

     

    4) Use the built-in database design and editing features within Visual Web Developer (note: this VWD is free) to create a new table with some basic list schema (and optionally add an “items” table as well for sub-items).  Make the listId column both the primary key, as well an identity column (with an auto-increment value of 1):

     

     

    Once the schema for the table has been defined, open up the lists table and add 3-4 rows of sample information within it (right click on the table in the server explorer and choose “Show Table Data” to-do this):

     

     

    5) Once you’ve built your database tables, close the database designer, and then select “Add New Item” on the project again.  Choose the “Dataset” item:

     

     

    Walkthrough the table-adapter wizard that runs by default to connect to the SQL database we just created and choose to build a data-adapter using a standard set of SQL statements:

     

     

     

     

    Name the select method we defined in the step above “GetListsByCompleteStatus” (or anything else you want to call it).  Note that you’ll be able to add any number of methods you want to the adapter later – and can define a separate SQL statement for each method (the adapter will then also by default generate automatic Insert, Update and Delete statements for the default Select statement in your adapter). 

     

    The adapter will encapsulate all of the ADO.NET data access code needed to execute them – and generate a strongly-typed set of data objects you can use.  For example, with the method we just defined above, you could now write the below code to use the strongly-typed adapter and corresponding datatables and datarows anywhere within our project:

     

     

    6) Create a new ASP.NET page in your project called “MyLists.aspx”.  Add a title called “MyLists”, then a drop-downlist onto the page, and edit its items to have two elements: “active” and “done”.  Set the value of “active” to false, and the value of “done” to true (we will use this to filter the “isComplete” field in our database).  Also make sure that you set the “Enable Auto-Postback” checkbox to true:

     

     

     

    7) Drag/drop a GridView control onto the page, choose “new datasource”, choose the “Object” data binding option, and choose to bind it to the data adapter we built above:

     

     

    8) Bind the default query operation against the “GetListsByCompleteStatus” method we defined above, and bind the isComplete parameter to that method to the drop-downlist we built:

     

     

     

    9) Then enable paging, sorting, editing and deleting with the grid:

     

     

    Lastly, you can optionally disable “viewstate” for the GridView, by setting its “EnableViewState” property to “false”.  With ASP.NET 2.0, the GridView and other controls no longer require ViewState to perform paging, sorting, updating and deleting operations.

     

    10) And then hit either F5 (to run and debug) or Ctrl-F5 (to just run) the app:

     

     

    If you click the “edit” button on any of the items, you will switch into edit more, and you’ll be able to edit and change the column values.  If you select “update”, the Grid will call through to the data adapter you built (or any intermediate class you built that you want to use to either encapsulate or sub-class it) and update the database for you.  A similar binding action happens with “delete” operations. 

     

     

    If you change the drop-down list selection, the grid will re-bind with the appropriate isComplete filter selection.  If you click on any of the columns in the grid, the row values will sort (ascending or descending).  If you add more than 10 values in the grid, page numbers (along with default page semantics) will show up at the bottom.

     

    11) If you click on the html source-tab, you can see what is persisted in the .aspx file:

     

     

    Basically, it contains our drop-down control definition, along with the GridView definition, along with an ObjectDataSource that provides declarative data-binding support.  You can write code and event handlers to customize any of the three controls in the code-behind file. 

     

    12) Our last step before adding Atlas functionality, will be to add a textbox and button to help us add new list items to our Grid:

     

     

    And then add a code-behind event handler that will fire when the “Add” button is clicked, and use our data adapter to insert a new list into the Lists table, and re-bind our grid:

     

     

    Note that there is no other code in our code-behind file. 

     

    Step 13) Try running the application again.  Now you can add, delete, update, sort, page and filter the data:

     

     

    Adding Atlas Support

     

    So far, all of the steps we have followed work with the vanilla ASP.NET 2.0 and Visual Web Developer tool products – we haven’t used any Atlas features yet.

     

    What we want to-do is to use Atlas to replace the built-in ASP.NET post-back model so that instead of refreshing the entire page when a post-back occurs, we use XMLHttp to only send back the regions of a page that have changed.  This enables us to make the page feel much more dynamic, perform faster, and obtain a much richer user-experience.

     

    Step 14) Our first step to add Atlas support will be to add the <atlas:scriptmanager> server control to the page, and set its “EnablePartialRendering” attribute to “true”:

     

     

    Step 15) We are then going to add an <atlas:updatepanel> control onto the page, and use it to wrap our GridView control and associated content:

     

     

    This is now an “updatable” region within our page – which means that when a post-back event occurs, Atlas will intercept the event, and instead of refreshing the entire page it will use XMLHTTP to just send back partial updates from the server, and then dynamically repaint those portions of the page.

     

    Try running the application again, and add a new item, then sort, filter, and edit items.  Notice how fast it feels – and the fact that the page wasn’t refreshed on each action. 

     

    Step 16) When running the above app, you might have noticed when you added a new item to the list, the textbox value wasn’t cleared.  This is because the textbox lived outside of the <asp:updatepanel> we added above – and so wasn’t refreshed as part of our post-back call.

     

    We could either move it to be inside the above <asp:updatepanel> or more optimally choose to add a new <asp:updatepanel> to the page that contains in.  This is more optimal because we will not update this panel every-trip to the server, but instead only when a declarative trigger that we’ll specify occurs (or alternatively if someone writes code on the server to explicitly trigger it). 

     

     

    The above trigger means that this panel will only be refreshed only if the “add” button fired (or if we wrote code on the server to explicitly refresh it).  This means it will not fire in response to the drop-down filter changing, or to sorts, edits, updates, deletes within the GridView.

     

    And now when we run our application again, it is ajax enabled, and allows us to dynamically add, remove, update, sort, page and filter our list items….

     

    The full-blown sample I showed at the beginning does a few more cool things, but the walkthrough above captures the basic concepts from it.  As you can see, building one of these types of apps be done in minutes, doesn’t require much code at all (you only have to manually write 4 lines of code total), and enables you to start building Ajax applications with a fraction of the concept count from before.

     

    Hope this helps -- and happy holidays,

     

    Scott

     

  • Upcoming Releases of Useful ASP.NET 2.0 Things

    A few people have asked me about what else is coming down the road in terms of downloads and other releases for ASP.NET 2.0.  Here is a non-exhaustive brain-dump of a few things coming out in the near future that we've been working on:

  • Free Microsoft Learning Online Course Available on ASP.NET 2.0

    Brad from the Microsoft Learning team just pointed me at a cool offer.  Basically it allows you to take a 3-hour ASP.NET 2.0 Training course for free if you register for it before January 4th (note: you then have up to 90 days after you register to take it).

  • How to Solve Beta Install Related Package Load Failures with VS 2005

    Right after VS 2005 shipped, a lot of people ran into "Package Load Errors" when trying to install and run the final release of the product.  These are often the result of having some left-over VS 2005 Beta or CTP bits that weren't uninstalled completely on the same machine.

  • Cross-Page Navigation Techniques in ASP.NET

    Ting (one of the key guys on the ASP.NET Team) has posted an awesome blog post detailing all of the different techniques for doing Cross-Page navigation in ASP.NET, including: client-side redirects, server-side redirects, the new ASP.NET 2.0 cross-page posting feature, the new ASP.NET 2.0 multi-view control, and the new ASP.NET 2.0 Wizard Control.  In his post he includes a sample for each.

     

    Definitely something I’d recommend to check out and review.

     

    Hope this helps,

     

    Scott

     

  • Cool SQL Server and SQL Express Command-Line Utility

    Brad on my team recently pointed me at a cool command-line SQL/SQL Express utility that might be useful for people to keep in the tool chest.  It is free and you can download it here.

     

    It includes a useful doc-file that walks-through the various commands it provides.  I also found this link useful in walking through how to use common SQL commands for creating new databases.

     

    Here is a simple set of steps that demonstrate how to use it to create a SQL Express database file, attach to it, create a database in it, then add a table, then add values into the table, then do a select query against it (note: all commands I typed are in bold below):

     

    C:\SQLUtility>sseutil -c

     

    Console mode. Type 'help' for more information.

     

    1> !create c:\sqlutility\testing123.mdf

    Command completed successfully.

     

    1> !attach c:\sqlutility\testing123.mdf

    Command completed successfully.

     

    1> use "c:\sqlutility\testing123.mdf"

    2> go

     

    Command completed successfully.

     

    1> create database people

    2> go

     

    Command completed successfully.

     

    1> use people

    2> go

     

    Command completed successfully.

     

    1> create table names

    2> (id INTEGER NOT NULL,

    3> name VARCHAR(50) NOT NULL)

    4> go

     

    Command completed successfully.

     

    1> insert into names values(1, 'bill gates')

    2> go

     

    1 row(s) affected.

     

    1> select * from names

    2> go

     

    id   name

    ------------------

    1    bill gates

     

    1 row(s) affected.

     

    1> quit

     

    Of course, an easier way to-do this from scratch would be to use Visual Web Developer or VS 2005 and select Add New Item->Database file, name it, and then use the server explorer to create and add the table.  But the nice thing about the above approach is that you can use it execute a SQL script file to quickly create/re-create your database without needing a tool on your system (or a user who knows how to use it).

     

    Hope this helps,

     

    Scott

     

    P.S. One other cool thing about this utility is that it allows you to list all databases you have installed on your system.  Just type sseutil –l to list all of the databases and .mdf files being used.  This is very helpful if you have multiple database instances on your system (for example: I have some SQL 2000 databases and some SQL 2005 Express ones).

     

  • Logging ASP.NET Application Shutdown Events

    Someone on a listserv recently asked whether there was a way to figure out why and when ASP.NET restarts application domains.  Specifically, he was looking for the exact cause of what was triggering them on his application in a production shared hosted environment (was it a web.config file change, a global.asax change, an app_code directory change, a directory delete change, max-num-compilations reached quota, \bin directory change, etc). 

     

    Thomas on my team has a cool code-snippet that he wrote that uses some nifty private reflection tricks to capture and log this information.  It is pretty easy to re-use and add into any application, and can be used to log the information anywhere you want (the below code use the NT Event Log to save it – but you could just as easily send it to a database or via an email to an admin).  The code works with both ASP.NET V1.1 and ASP.NET V2.0.

     

    Simply add the System.Reflection and System.Diagnostics namespaces to your Global.asax class/file, and then add the Application_End event with this code (note: you can also download a .zip file containing the code from here):

     

    public void Application_End() {

        

        HttpRuntime runtime = (HttpRuntime) typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime",

                                                                                        BindingFlags.NonPublic

                                                                                        | BindingFlags.Static

                                                                                        | BindingFlags.GetField,

                                                                                        null,

                                                                                        null,

                                                                                        null);

       

        if (runtime == null)

            return;

       

        string shutDownMessage = (string) runtime.GetType().InvokeMember("_shutDownMessage",

                                                                         BindingFlags.NonPublic

                                                                         | BindingFlags.Instance

                                                                         | BindingFlags.GetField,

                                                                         null,

                                                                         runtime,

                                                                         null);

       

        string shutDownStack = (string) runtime.GetType().InvokeMember("_shutDownStack",

                                                                       BindingFlags.NonPublic

                                                                       | BindingFlags.Instance

                                                                       | BindingFlags.GetField,

                                                                       null,

                                                                       runtime,

                                                                       null);

       

        if (!EventLog.SourceExists(".NET Runtime")) {

            EventLog.CreateEventSource(".NET Runtime", "Application");

        }

       

        EventLog log = new EventLog();

        log.Source = ".NET Runtime";

        log.WriteEntry(String.Format("\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}",

                                     shutDownMessage,

                                     shutDownStack),

                                     EventLogEntryType.Error);

    }

     

    I tried this out using a simple web-site using ASP.NET 2.0 and the built-in VS Web-Server (aka Cassini).  When I changed the web.config file in my running application, the following was logged to my "Application" event viewer:

    _shutDownMessage=CONFIG change

    HostingEnvironment caused shutdown

    CONFIG change

    CONFIG change

    _shutDownStack= at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

    at System.Environment.get_StackTrace()

    at System.Web.HttpRuntime.ShutdownAppDomain()

    at System.Web.Hosting.HostingEnvironment.ShutdownThisAppDomainOnce()

    at System.Web.Hosting.HostingEnvironment.InitiateShutdownWorkItemCallback(Object state)

    at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)

    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

    at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state).

     

    When I updated my Global.asax file with some code change, the following was logged:

    _shutDownMessage=Change in GLOBAL.ASAX

    Change in GLOBAL.ASAX

    Change in GLOBAL.ASAX

    HostingEnvironment caused shutdown

    _shutDownStack= at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

    at System.Environment.get_StackTrace()

    at System.Web.HttpRuntime.ShutdownAppDomain()

    at System.Web.HttpApplicationFactory.OnAppFileChange(Object sender, FileChangeEvent e)

    at System.Web.DirectoryMonitor.FireNotifications()

    at System.Web.Util.WorkItem.CallCallbackWithAssert(WorkItemCallback callback)

    at System.Web.Util.WorkItem.OnQueueUserWorkItemCompletion(Object state)

    at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)

    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

    at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state).

     

    And when I changed the contents of my \bin directory I got:

    _shutDownMessage=Change Notification for critical directories.

    bin dir change or directory rename

    HostingEnvironment caused shutdown

    Directory rename change notification for 'E:\Unload'.

    Unload dir change or directory rename

    _shutDownStack= at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

    at System.Environment.get_StackTrace()

    at System.Web.HttpRuntime.ShutdownAppDomain()

    at System.Web.Hosting.HostingEnvironment.ShutdownThisAppDomainOnce()

    at System.Web.Hosting.HostingEnvironment.InitiateShutdownWorkItemCallback(Object state)

    at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)

    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

    at System.Threading.

    Hopefully this is a useful trick that you can re-use in your own applications to get better visibility into what is going on with them.  If you are using ASP.NET 2.0, then you should definitely also investigate the new ASP.NET 2.0 Health Monitoring feature-set.  This provides a rich eventing architecture for instrumenting your code, as well as raising notifications of issues to admins when they occur within your application.  K. Scott Allen has written a good overview article of how this new feature-set works, and links to the MSDN documentation.

     

    Hope this helps,

     

    Scott

  • "CSS Properties Window" Download Available for VS 2005

    One of the process things we've been doing on our team lately has been to provide an opportunity for team members to spend time building and shipping personal projects that enhance the core shipping products.  On the updated www.asp.net site that we launched last month, we created a "Sandbox" tab that provides an outlet for team members to make these projects available to the public.  Over time you'll start to see more and more projects appear there that you can take advantage of with web development.

  • Grid and Flow Modes in VS 2005 and Visual Web Developer

    One of the changes made between VS 2003 and VS 2005 was to change the default page layout mode in the WYSIWYG designer from "Grid" to "Flow" mode.  Mike Pope has a good post that talks about how to enable and still use 2D grid-layout mode if you prefer that.  One nice addition is the ability to optionally use absolute/grid layout on just individual controls instead of having to-do it for the entire page.

  • Sending Email with System.Net.Mail

    .NET 2.0 includes much richer Email API support within the System.Net.Mail code namespace.  I've seen a few questions from folks wondering about how to get started with it.  Here is a simple snippet of how to send an email message from “sender@foo.bar.com” to multiple email recipients (note that the To a CC properties are collections and so can handle multiple address targets):

     

    MailMessage message = new MailMessage();

    message.From = new MailAddress("sender@foo.bar.com");

     

    message.To.Add(new MailAddress("recipient1@foo.bar.com"));

    message.To.Add(new MailAddress("recipient2@foo.bar.com"));

    message.To.Add(new MailAddress("recipient3@foo.bar.com"));

     

    message.CC.Add(new MailAddress("carboncopy@foo.bar.com"));

    message.Subject = "This is my subject";

    message.Body = "This is the content";

     

    SmtpClient client = new SmtpClient();

    client.Send(message);

     

    System.Net.Mail reads SMTP configuration data out of the standard .NET configuration system (so for ASP.NET applications you’d configure this in your application’s web.config file).  Here is an example of how to configure it:

     

      <system.net>

        <mailSettings>

          <smtp from="test@foo.com">

            <network host="smtpserver1" port="25" userName="username" password="secret" defaultCredentials="true" />

          </smtp>

        </mailSettings>

      </system.net>

     

    Hope this helps,

     

    Scott

     

    P.S. Many thanks to Federico from my team for putting the above sample together.

     

  • Configuration Section Code Generator and XML Intellisense Schema Builder for Web.Config files

    Dmitry (the Dev Manager for ASP.NET) has been working in his spare time on building a cool disk-based output caching module for ASP.NET 2.0 (he is planning to post it on the web once it is done).  One of the things he discovered in building it was how repetitive it was to have to hand-generate configuration section handlers for web.config files, as well as the intellisense schema files to provide intellisense support for them in VS 2005.

  • Building your own Data Source Controls in ASP.NET 2.0

    ASP.NET 2.0 introduces a powerful new declarative data-source model.  Among other things, it makes doing data access much easier in a stateless-web world -- and eliminates many of the hurdles developers have to jump through today to handle repeated data UI operations on the server.  Included in the box is the new ObjectDataSource control, which you can use to databind to any .NET class -- no special databinding interfaces are required, and it enables pretty easy three-tier databinding scenarios.

  • Cache Manager

    Steve Smith has written a cool application that helps you monitor and manage your cache values in ASP.NET.  Read all about it and track its progress here.

  • VS 2005 Intellisense in web.config files

    I’ve seen a few questions about intellisense support for ASP.NET web.config files with VS 2005, and thought I’d blog a quick post to answer a few of them.

     

    First the good news:

     

    VS 2005 now supports intellisense for web.config files you add to your web project (yea!).  It uses the new XML editor (which btw is much better in VS 2005), and has a built-in schema for all of the built-in .NET Framework settings:

     

     

    Now one annoying gotcha:

     

    There is one gotcha to be aware of, though, that can sometimes cause intellisense for the web.config file to stop working in the IDE.  This happens when a default namespace is added to the root <configuration> element.  For example, like so:

     

                <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

               

    This doesn’t cause any runtime problems – but it does stop intellisense completion happening for the built-in .NET XML elements in the web.config file. 

     

    The bad news is that the built-in web admin tool (launched via the WebSite->ASP.NET Configuration menu item in VS 2005 and Visual Web Developer) always adds this xmlns namespace when it launches – so if you use this tool to manage users/roles you’ll end up having it added to your web.config file for you.

     

    How to fix this gotcha:

     

    To get intellisense back when you are editing the web.config file in the IDE, just delete the xmlns reference and have the root configuration element look like so:

     

    <configuration>

     

    Everything will then work fine again.

     

    Hope this helps,

     

    Scott