The fact that you can assign namespace and assemblies in your web.config file is one of the most underused features of ASP.NET I think. I was working with a customer today and when I demonstrated an example he noted that I got my custom controls to show up in page markup without having an explicit @Register tag in the page. Usually when you embed a custom control into a page you need to add a @Register tag like so:

<%@ Page language="c#" Inherits="Westwind.WebToolkit.MessageDisplay" 
                       enableViewState="false"   AutoEventWireup="True" 
<%@ Register Assembly="Westwind.Web" Namespace="Westwind.Web.Controls" TagPrefix="ww" %>  

in order to get a control to work in the page and show up with Intellisense. If you’re using the visual designer to drop controls you probably won’t notice this requirement because the designer automatically adds the assembly and namespace dependency for you into the page. However if you work in markup only as I do mostly, it’s often annoying to first have to register the control on the top of the page and then go back to actually embedding the control into the page to get Intellisense.

An easier and application global way to do this is to declare your namespaces and control tags directly in web.config and have them apply globally:

<pages> <namespaces> <add namespace="System.IO" /> <add namespace="System.Text" /> <add namespace="Westwind.Utilities" /> <add namespace="Westwind.Web.Controls" /> </namespaces> <controls> <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add tagPrefix="ww" namespace="Westwind.Web.Controls" assembly="Westwind.Web" /> </controls> </pages>
    <compilation debug="true">
        <add assembly="System.Core, Version=, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
        <add assembly="System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />

The controls section is what provides effectively the equivalence of the @Register tag in pages and once you’ve defined the tag prefix there the @Register tag is no longer required in the page.

The Namespaces section does something similar the the @Import tag in the page header by allowing you to define global namespace definitions that replace things like:

<%@ Import Namespace="Westwind.Web.Controls" %>

but on a global scale. The @Import is typically used to make namespace references available in your page so that page server code doesn’t need to use fully qualified types for everything. This helps keeps your code shorter

<%= StringUtils.DisplayMemo( Item.Description ) %>

instead of

<%= Westwind.Utilities.StringUtils.DisplayMemo( Item.Description ) %>

You do want to keep your namespace lists reasonable just like you should in all code to keep the compiler from having to do name resolution on its own. Remember ASPX pages compile once at runtime (unless you use the ASP.NET compiler) during startup and lots of extra namespaces do add some overhead during compilation.

Behind the scenes the ASP.NET compiler injects the namespace references into all generated pages and the assemblies as references to any of the dynamic assemblies it creates. By default ASP.NET includes all assemblies in the bin path, plus any GAC based assembly references in the <compilation> section of web.config. Note that you don’t need to add any private assemblies in this section – it’s only needed to add GAC references. All private assemblies in BIN folder are automatically referenced.

This isn’t exactly news – this feature has been there since ASP.NET 2.0, but it does make life easier especially if you have markup pages that utilize external utility libraries frequently.