C# – Converting a Page to a User Control

asp.netcnetuser interfaceuser-controls

If we want to convert a Page to user control then we should also do the following:

“If you aren’t using the code-behind model, make sure you still include a class name in the Control directive by supplying the ClassName attribute. This way, the web page that consumes the control can be strongly typed, which allows it to access properties and methods you’ve added to the control..”

I’m not sure I understand the above quote:

Namely, if we don’t use code behind class, then ascx class will derive directly from UserControl class!
Thus if we don’t use code behind class, then there won’t be any methods or properties added to a control, so why would web page have problems accessing any of user control’s properties and methods? So why would we need to include a class name in Control directive?

thanx

Best Answer

I think I should clarify how the compilation model works. First of all, you can write everything (including C# code) in a single .ascx file and inherit from whatever class you want to (that ultimately inherits from UserControl) by specifying Inherits attribute (or you might want to omit it) and without a ClassName attribute. If you do this, you can still access the properties from the .aspx file that uses this control. The thing is, you can't use the class in the codebehind file of .aspx page (if it has one) directly. By specifying the ClassName, if you are using the Website project model of Visual Studio, you can access it from the .aspx.cs file too. Note that this would not work in Web application project model as every .cs file will be compiled ahead of the time (prior to the .ascx file). In that case, even ClassName attribute wouldn't help much.

In any case, strictly none of the attributes are necessary. You can always use the properties defined anywhere in .ascx or .ascx.cs file included in a page in the .aspx file (but not always .aspx.cs file).

Edit to address the update to the question:

A) From your source code, it seems you are using the Website model here. Note that I mentioned you cannot use the class directly. I agree this statement might have been a little misleading. What I wanted to note is that without a ClassName, ASP.NET will choose a name for your user control class but that name is not guaranteed. While you can use the generated name, it's not recommended at all. You should treat it pretty much like an anonymous type where you can use an instance but cannot mention a name. In your example, you are basically referencing an instance (which is constructed on the .aspx markup), not the class, which is OK.

B) What you are saying is correct. Whatever you declare in ascx.cs in a Web application will be visible to .aspx.cs and .aspx. What I was talking about is properties that you declare in .ascx in a <script runat="server"> tag. Those will not be visible to .aspx.cs since it's compiled beforehand.

C) ASP.NET will generate the class defined by the ClassName attribute in the ASP namespace. You should use ASP.Some_Name instead. There is one thing I forgot to mention: in this case, you should somehow reference the .ascx in the .aspx markup; either with a Reference directive (<%@ Reference Control="MyControl.ascx" %>) directive or with a Register directive (<%@ Register TagPrefix="abc" TagName="xyz" Src="MyControl.ascx" %>). This will ensure that the ASP.NET build engine puts the generated .ascx class in the same assembly as .aspx page.