Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config


:P
On this page:

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" 
                       CodeBehind="MessageDisplay.aspx.cs"  
                       enableViewState="false"   AutoEventWireup="True" 
                       MasterPageFile="~/WestWindWebToolkit.master"
%>
<%@ 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:

<system.web>
<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=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add tagPrefix="ww" namespace="Westwind.Web.Controls" assembly="Westwind.Web" /> </controls> </pages>
    <compilation debug="true">
      <assemblies>
        <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
        <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </assemblies>
    </compilation>
</system.web> 

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.

Posted in ASP.NET  

The Voices of Reason


 

Valamas
May 04, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

Any ideas on how to do the same for namespaces in code behind or class library projects?

Rick Strahl
May 05, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

@Valamas - There's no way to define a set of global namespaces AFAIK. The reason this works in ASP.NET is that the ASP.NET compiler injects it into the generated code for the markup pages. It doesn't work with code behind.

But in regular C#/VB code it's easy enough to do with Shift-Alt-F10 on and then auto-injecting the namespace reference. One of the most used hotkeys for me in VS. Totally on auto-pilot.

Random Guy
May 05, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

Control + . is easier to type...stead of Shift-Alt-F10.

John Stagich's Blog
May 05, 2009

# May 2009 Quick Hits

May 2009 Quick Hits

Rick Strahl
May 05, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

@Random Guy - I've heard that but this has never worked on my setup. Not sure why probably some hotkey overlaps but Ctrl+. does nothing for me. Ctrl-Shift-F10 always works but yeah it's a 'handful' :-}.

Shail
May 06, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

Hello Rick,
Good shortcut. I have one question. I want to do same for UserControls in my webs site. I have a folder called as controls in my web site and I want that all controls from that folder should be available to all pages. Like I want to register a control called "User.ascx" globally.

Peter
May 07, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

Sadly this does not work for sub-project pattern* sites where it would be incredibly useful for eliminating tons of work during version-ing upgrades of various controls suites.

* How To: Create an ASP.NET Application from Multiple Projects for Team Development (Q307467)

Abhilash
May 12, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

Hi, thanks for the tip.

I got one doubt in below code.

---
<pages>
<namespaces>
<add namespace="System.IO" />
<add namespace="System.Text" />
<add namespace="Westwind.Utilities" />
<add namespace="Westwind.Web.Controls" />
</namespaces>
---
what is the 'exact' use of "<add namespace="System.IO" />" in the web.config ?

Does that mean, the namespace will be globally available within the context of our project. In short, we can declare the classes in the "System.IO", without specifying the namespace in code-behind ? Is that it meant for?

If true, I tried to add StreamReader class in code-behind, without specifying the namespace "System.IO". But, I's welcomed with a compile-time error.

Then what is the 'exact' use of '<namespace>' tag in the '<page>' element ?

Thanks & Tc.

Rick Strahl
May 12, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

@Abilash - the pages/namespace tag only applies - as the hierarchy implies - to ASPX/Master/ASC etc. pages. Anything the ASP.NET compiler compiles basically. It does NOT apply to code behind. In CodeBehind it's easy enough to apply namespaces - it's in ASPX pages where @Register and @Namespace tags are required where the verbose syntax and lack of automatic insertion make this a little more difficult.

Andrew
June 18, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

That's exactly what I was looking for...

Regards...

Aman Tur
June 25, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

Rick I used your suggestion and put the control tags in my web.config. I was able to add usercontrols to my pages without using <%@ Register tags on each page but I got NullReferenceException for controls inside user controls. More details are here in this stackoverflow questions: http://stackoverflow.com/questions/1042383/usercontrol-working-in-one-page-but-not-in-others

rAdmin
July 23, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

Dead on! Thank you for posting this.

ColinW
August 15, 2009

# re: Adding Default Assemblies, Namespaces and Control Prefixes in Web.Config

Are you missing the assembly references in the assembly section?

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024