Namespaces and ASP.NET 2.0

Wednesday, February 8, 2006

I've seen grumbling lately over the lack of namespaces in ASP.NET 2.0 projects.

With Visual Studio 2003, if I add a page with the name of WebFormA to a folder with the name of FolderA, inside a project (named ProjectA), then the IDE starts off with a code-behind file that looks like the following.

namespace ProjectA.FolderA
{
   
/// <summary>
   /// Summary description for WebFormA.
   /// </summary>
   public class WebFormA : System.Web.UI.Page

The same steps with web project model in Visual Studio 2005 produces the following.

public partial class FolderA_WebFormA : System.Web.UI.Page
{

Some people believe having a class declared outside of a namespace is an unthinkable tragedy. My question is why?

One reason to use a namespace is to avoid type name collisions. By appending folder names to the front of the class, ASP.NET is avoiding name collisions (although I do wonder when someone will bump up against the max identifier length).

A second reason for using a namespace is to present a logical, organized hierarchy for consumers of the types. Who is the consumer of a WebForm? Typically only the ASP.NET runtime, which doesn’t need a namespace to help it map an HTTP request to an HttpHandler.

Types in a code-beside file are well hidden. The compilation model for ASP.NET 2.0 may even put each type in a separate assembly. In the scenarios where a Page, UserControl, or MasterPage code-beside type is needed outside of it’s own definition, the @ PreviousPage, @ MasterType, and @ Reference directives are needed. Pretending that these types are anonymous isn’t a bad idea. Using a base class or an interface will reduce the tight coupling that occurs when user control and master page types are used by other areas of an application.

If you still need to put Page derived types in a namespace, you'll want to consider using the Web Application Project type, which works like the 1.1 model.


Comments
Anatoly Lubarsky Wednesday, February 8, 2006
The first reason is code maintainability.

Anther thing is web services project, where there may be different consumers, it is not really a front end.
Paul B Monday, February 13, 2006
What about ASP.NET 1.1 projects that have been converted to 2.0? Now the developers need to either:
a) Fix all the converted code to match the new standard
b) Fix all new classes to use the 1.1 scheme as they are created.
c) Live with inconsistancy in naming and namespacing.

None of these options seem particularly appealing. Is there a 4th option that I'm missing?
scott Tuesday, February 14, 2006
Paul:

I think the 2.0 migration is rough. The new Web Application Project will make the job easier and keep code consistent, but that's no good if you've already converted. :(
Matt Wynne Thursday, February 23, 2006
Thanks for the article Scott, it's shed some light on a rather murky corner of the new ASP.NET 2.0 functionality.

I've come across this article as I've hit a snag caused by this new 'web site' vs 'web app' feature in 2.0, and it seems to me I may have found a case for going back to the namespace model. This is my first 2.0 project, though, and I may just be missing something in understanding how it's all supposed to work.

I have a few similar pages which use a single MasterPage. On the MasterPage I've defined a control for displaying messages, and each page can set the property (MyMasterPage)Master.UserMessage to have their message displayed. All groovy so far.

Now suppose I want to make the call to display the message a bit more complex. Maybe I want to trap exceptions bubbled up to the page, log them to the database and display a helpfull message to the user. Logically, for me, I would abstract this code into a base class from which each of the pages derives, so the page calls base.HandleException(ex) and the base class deals with it.

Now I hit the snag: the base class, which seems to need to live in ~/App_Code cannot see the MyMasterPage type. So I can't call MyMasterPage.UserMessage from BasePage because it doesn't know what MyMasterPage is.

Now if they were all in the same namespace (as in 1.1) I'm pretty sure this wouldn't be happening.

Maybe the intended solution is that I put my error logging code in the masterpage's codebehind file, but this doesn't feel right somehow. Not a very good reason I know, and I'll give it a try now...
Duray AKAR Saturday, March 11, 2006
I was just looking for a solution for the thing you have just mentined, and I found this blog.

I think that leaves us with an approach to encapsulate the reusable code ina separate project, most likely a class library, then make calls to that library within asp.net 2.0

But I run into this issue as I was trying some AJAX.Net 2.0 code...

I don't know what to do with that ...

:)

jenad1kr Monday, March 20, 2006
I am looking for a solution where I can access my page in my user control.
like

in my ascx page_load

if typeof(me.page) is myhostingpage then
' addhandler for page event to a method here
end if

with 2003 i did not have any problems, the pages in the project are accessible across other controls and pages.

but in 2005, I am not able to find myhostingpage at all in my ascx. Is this approach a right one, even if its not, there has to be a way to access my page properties in my user control. right?
scott Tuesday, March 21, 2006
jenad1kr: that's a tough one, because if the Page @ References the user control and the user control @ References the page, there is a circular reference.

How about defining a base class in App_Code and letting the user control interact with the page through the base class?

Alternatively, you could just have the user control raise an event for the page to handle, or some other approach where the page passes a delegate for the user control to fire.
jenad1kr Tuesday, March 21, 2006
Scott: Thanks for the quick respose. the reason why i need to communicate from page to user control is this. i am using the following layout for my pages.

<asp:content>
<asp:Wizard>
</asp:Wizard>
<HeaderTemplate>
<asp:WebPartZone>
<ZoneTemplate>
<asp:gridview />
</ZoneTemplate>
</asp:WebPartZone>

</HeaderTemplate>

<WizardSteps>
<%-- Method1 -->
<asp:WizardStep>
<asp:WebPartZone>
<ZoneTemplate>
<UC:usercontrol />
</ZoneTemplate>
</asp:WebPartZone>
</asp:WizardStep>

<%-- Method2 -->
<asp:WizardStep>
<asp:WebPartZone>
<ZoneTemplate>
<asp:panel>
-- All the controls in the user control go here directly
</asp:panel>
</ZoneTemplate>
</asp:WebPartZone>
</asp:WizardStep>
</WizardSteps>
</asp:content>

I have the above design in one of my pages.
I need to get/set values, properties for my controls inside the webpartzone.

Problem1: accessing the controls is pain in the neck.

problem2: if i try to use a generic findcontrol and pass the wizard.controlscollection, webpartzone does not have the same behaviour for HasControls property. so i have to go into the zone.webparts collection and iterate under each webpart to get to my control.
this will be a killer as far as performance is concerned.

I am trying to make full use of web parts. Is there a easier way to "find" controls in wizard and in webpartZones? (both method1 and method2)

IF there is a way, then i dont need to worry about catching events in my user control from my page. your time is much appreciated. thanks!
will Sullivan Monday, April 17, 2006
Here's the bitch of it... You can't easily (maybe not at all) set the protection level for your helper class methods to anything less than Public, or you can't access them from your pages. I have an object that interacts with the security of the backend system, including a method that clears out all licenses held by the system (something that definitely shouldn't be public). I have them marked all internal, and because 2.0 plays funky ass games with projects now I can't just reference the helper class. I get errors telling me that the methods are inaccessible due to the protection level. Nice.
scott Tuesday, April 18, 2006
Will: I tend to think of App_Code as a class library in another project. If I want to expose functionality from App_Code it has to public.

I don't think the role a class plays changes it's accessibility. That is, just because I make a licensing component protected, internal, or private doesn't make it "safe" from someone who shouldn't be calling it.
Kiran Friday, April 28, 2006
Hi Scott...
I am through my first project in asp.net 2.0..
I have the same problem..
First of all I didn't like the app_code this.
Again I have a simple helper class in the AppCode with a namespace..The pages are not able to find the classess.

Even if its one helper class ..We should build a separate Library Project..Is that the only way out?
scott Sunday, April 30, 2006
Hi Kiran:

If you don't like App_Code then a class library project will work. App_Code should work, too, if the classes are public.
gravatar ayc# Monday, May 3, 2010
I faced same problem, that is accessing user control's login button in a master page from a child page. But I failed to access the code behind cs class of user control. I tried this using a class in the app code folder and using getters setters but with no result. I finally solved the problem using session variable.
Hieu Le Wednesday, August 11, 2010
Can you give demo code to reference control in app_code?
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!