Why don't my user controls render? - asp.net

I've created a set of user controls in vb.net and in their original project they work fine.
I've since created a user control library dll and I wish to use it in a new project.
I add the reference to the dll fine, specify the tag library in an asp.net page fine and define controls on the page fine.
Everything seems to work except I get no rendered output.
Various properies of the controls and the page_load methods are all called.
Asp.net trace shows the controls in the page hierarchy etc
Just no output where the controls should be - any suggestions?
Update 1
I just compared a trace of the working output compared to the non working.
The working output contains the user controls (and all elements in them)
The non working output only lists the user controls - no content
It therefore seems that the content of the controls is missing somehow - as if the markup is not being compiled with the codebehind, only the codebehind seems to be working.
Update 2
The controls are inheriting from UserControl not control.

You are correct in your summarization in Update 1- your markup has not been included!
You need to provide a bit of elbow grease if your trying to distribute .ascx controls in a .dll but not too much thankfully.
The two main things you need to do:
Embedded your .ascx controls. The .ascx controls need to be marked as an embedded resource in your .dll (as oppossed to 'content')
Create a VirtualPathProvider. This will allow you to load the ascx files directly from the dll they are embedded in.
Unfortunately explaining step 2 is slightly lengthy, however this excellent article helped me out in doing exactly what you want to do.
The beauty of distributing .ascx controls like this is that you dont have to tear your hair out writing custom controls (rendering anything over than very simple html is a nightmare to make sense of).

I assume that you are not confusing between user control (.ascx) and custom controls. For user controls to work, one needs both ascx (mark-up file) along with corresponding code-behind class. User control are typically consists of constituent child controls whose hierarchy is specified within ascx file that provides some UI. In a class library (dll) project, you cannot package ascx files - all you get is the code-behind class. Without ascx, the code-behind class will not have any child controls and hence will render empty. In short, you cannot package user controls (ascx) in a class library - you have to add them into your actual web project.
For shared control, one has to use custom controls. Custom controls are code-only and typically provides render override that emits necessary html (or creates the own child control tree dynamically). These controls can be package as a class library and shared across project. Typically, a custom control will also have other helper classes to provide design time assistance (UI Editors etc).

Related

How are custom controls instantiated in asp.net?

My understanding is that when a component or custom control is defined in an aspx page using the <%Register%> tag, it is declared in an auto-generated designer.cs (C#) file by the compiler. If this custom control is never used in the aspx page, does this still happen in the designer.cs file?
Assuming the control is used in the aspx page, what mechanism then instantiates this control, how is it new-ed up behind the scenes? The designer file only declares it. Thanks much, and if there are good articles out there discussing this I’d be happy to read them.
This may not answer all your questions, but some of them. Rick Strahl wrote a great article a while back on compilation and deployment that describes how it works:
Compilation and Deployment in ASP.NET 2.0
I added part of the article that I think relates most to your question below:
Referencing other Pages and Controls
Remember that page and control compilation happens on a per directory basis! So referencing other pages and controls becomes a little more tricky for ASP.NET 2.0, because you can no longer assume that a CodeBeside class from another page or control is available in the current assembly. At best all pages and controls in the same directory end up in the same assembly, at worst each page or control gets its own assembly and they know nothing about each other.
If you need to reference another page from a control or another page you need to explicitly import it with the #Reference directive. Again this is different than ASP.NET 1.1 where all CodeBehind classes were immediately available to your entire Web application. In ASP.NET 2.0 an explicit assembly reference is required to load it.
Assume for a minute that you have the DataEntry.aspx page I showed earlier and you want to create a second page that uses the same CodeBeside class so you can reuse the page logic, but change the page layout in DataEntry2.aspx by changing a few colors and moving around the controls of the page. In essence you want to have two ASPX pages reference the same CodeBeside file.
Here’s how to do this:
<%# Reference Page="~/DataEntry.aspx" %>
<%# Page Language="C#" AutoEventWireup="true" Inherits="DataEntry" %>
I’m leaving out the CodeFile attribute reference the CodeBeside class of the DataEntry page, and add the #Reference tag to the page to force the CodeBeside class to be imported.
The same is true with any User Control definitions. To import a user control you need to use the #Register tag, which imports the assembly that the control lives in. ASP.NET is smart during compilation and figures out exactly where related assemblies live based on how the project is compiled. If the control or page lives in the same assembly no reference is actually added. But if it is external – in another directory for example, then the assembly reference is added.
Referencing problems
If you can explicitly reference other pages and controls in your markup pages, then all works well and as expected. But if you dynamically load controls or reference pages dynamically in your code, things get a lot more complicated.
The most common problem I run into is dynamic loading of controls. In ASP.NET 1.x you might have run code like this for dynamically loading controls into a page:
public partial class DynamicControlLoading : System.Web.UI.Page
{
protected CustomUserControl MessageDisplay = null;
protected void Page_Load(object sender, EventArgs e)
{
MessageDisplay = this.LoadControl( "~/UserControls/CustomUserControl.ascx") as CustomUserControl;
this.Controls.Add(MessageDisplay);
}
protected void btnSay_Click(object sender, EventArgs e)
{
this.MessageDisplay.ShowMessage(this.txtMessage.Text);
}
}
CustomUserControl in this case is a simple User Control that lives in another directory and is loaded dynamically at runtime. Further assume that you truly dynamically want to load this control so you may have a choice of several controls, or the end-user might even create a custom control that gets dropped into place instead.
If you run the code above in ASP.NET 2.0 it will likely fail. I say likely because there are some inconsistencies that will sometimes pick up control references automatically, for example if the user control lives in the same directory and gets compiled into the same assembly as the page, or if another page has the control referenced.
It should and usually will fail. Why? Because ASP.NET compiles on a directory level and the CustomUserControl lives in a separate directory and so goes into a separate assembly. It’s not visible to page class to get a strongly typed reference. Intellisense will show a big, fat and red exclamation point or nothing at all for the MessageDisplay control. When you run the page it will bomb.
You can reference the control as the Control type of course, but if you need to access any custom properties on the user control beyond Control properties you can’t unless you resort to Reflection. As far as I know there’s no way to add a reference to another user control or page programmatically because the reference needs to be available way earlier at compile time before your code ever runs.
Alternatives are to not load controls dynamically or at least provide some mechanism to load up any user controls beforehand on a page with the appropriate #Register tags. But that’s not always possible. The other option is to create a user control base class in APP_CODE and expose the public interface there. The main problem with this is that this base class will not have access to any internal controls of the user control and so the base class would have to use FindControl to reference any embedded controls. So this is inefficient as hell, and cumbersome to boot.
I’ve run into similar situations with inheritance scenarios. For example, inheriting one master page off another’s CodeBeside class. All works well, but the ASP.NET compiler complains that the Profile object is being overridden illegally (a compiler warning). Running with the inherited master page works, but there are quirks. User Controls added to the master page often fail with type conflicts as ASP.NET treats the user control added to the base page as a different type than the user control added to the second page.
It’s inconsistencies like these that deal with referencing other types that have made me waste an incredible amount of time, thinking I had something fixed only to find out later that it didn’t actually work consistently when I changed a completely different page. Worse you have to really understand the model to get your head around what might be wrong.
Bottom line: The overall ASP.NET 2.0 compilation model is internally complex. Most of the time you don’t need to understand it, but when you run into these boundary scenarios, you really DO have to understand what goes on behind the scenes to be able to work around the quirks.

why not user control?

why should be used use control template in asp.net? please, someone say me.
Can anyone tell me why I should use a Control Template over a UserControl in ASP.Net?
If you're familiar with MVC, a User Control is like the WebForms equivalent of a partial view.
Update (when I answered, the question asked when to use a User Control...):
A server control is appropriate when you want to bundle assets and functionality for wider distribution than a single project. It is more complex to develop a server control than it is a User Control, but a server-control allows you to completely encapsulate HTML, CSS, JavaScript, images, and server-side logic within a single DLL.
Conversely, a User Control is much easier to develop, but cannot contain assets such as external CSS/JS or images. User Controls are basically just partial bits of an ASPX page.
Unless you know that you need the features of a server control, I would always recommend a User Control for simple de-duplication of content that's repeated in multiple ASPX pages.
A User Control enables you to create your own custom control modules. They're useful because they are reusable, meaning you don't have to duplicate a lot of code. You can embed them in ASP.net pages, and you can define methods and properties for them.

How to get a composite-control's child controls at design-time

I am designing an ASP.NET v3.5 custom control based on CompositeControl.
However, I do NOT want to create my child controls via code, but rather as
embedded HTML tag elements within the CompositeControl in the ASPX page, such as:
<cc:MyCompositeControl ID="MyControl">
<asp:Label>Cat</asp:Label>
<asp:Label>Cat</asp:Label>
</cc:MyCompositeControl>
At run time, MyControl.Controls contains the two labels as expected.
At design time, MyControl.Controls is empty.
I need this information at design time for various reasons.
What am I doing wrong?
You might consider taking a look at the System.Web.UI.WebControls.Panel control in the System.Web DLL using Reflector. That will help you get some idea of what properties and what attribute decorations are necessary to provide the design-time support you need.

ASP.Net Custom controls vs. user controls: Are these two the same

If they are different, under what circumstances should we decide to use either approach?
Also, what is the advantage of ascx over aspx?
user controls are a form of custom control, that gives you a visual designer. They are ideal for use when you want a reusable control within the same web site. (It is possible to create and package user controls as seperate assemblies but that is beyond the scope of this question and I know has been asked on SO).
A custom control is typically used to refer to a Web Control, or a Composite Control which is specialized form of a web control. These controls have no designer and are usually implemented in seperate projects from your web allowing them to be reused accross many sites.
Now your second question, ASCX and ASPX are two different things. ASCX is the extension for a User Control, where as ASPX is an ASP.Net Page. You cannot use an ASCX by itself it must be placed onto an ASPX or Master page.
One way I like to use user controls is I have for example a very complex page which have 7 tabs, 5 of those have grids, of those grids three of them are identicle. Well what I can do is create a seperate user control for the content of the tabs, this now reduces the code I need down significantly (Since three grids are identicle except for the data).
Further more it allows multiple to work on various parts of the page, and it helps me keep everything straight since I am reducing the complexity of the page. You do not use User Controls instead of Pages, you use them in conjuction with a page.
Edit
You do not use ascx over aspx. You use ascx to complement. For example on my site every page has the same footer, but I don't want every page to derive from a single master page. I can create my footer as an acsx control and put it in each of my master pages.
Another example, I have a form that lets a user enter three different date ranges. (And we have other forms). So I put the logic to enable a calender button, and a text box that when clicked on opens up the calender, in a user control. I can then reuse that user control in all my aspx pages.
Custom controls are control build entirely in code. The pro is that you can put them in libreries, add an icon to the toolbox and other fine control.
User controls are more easy to do, and in general is a way to encapsulate things to simplify other pages or when you need to use the same markup in several pages.
The advantage of controls over regular aspx pages is that you only need to do some part of the markup (not the whole page)
User Controls/Composite controls
User controls that are made up of other ASP.Net or custom controls. They are usually quite straight forward and can be created quite quickly. They Are generally not shared across projects however there are some tricks that can allow you to do this.
Custom controls
Custom controls are controls that you implement the UI by creating everything from the HTML output to design time support. Custom controls take much longer to make. You must use either Web.UI.Control or inherit from a sub control (Textbox for example). Custom controls are compiled to binary format to allow them to be distributed more easily. Since they are compiled they can be referenced from the toolbox in visual studio.
There are 2 main advantages to using a control in an aspx page. Encapsulation of logic and reuseability.

What is the difference between UserControl, WebControl, RenderedControl and CompositeControl?

What is the difference, what is the official terms, are any terms obsolete in ASP.NET 3.5?
UserControl: A custom control, ending in .ascx, that is composed of other web controls. Its almost like a small version of an aspx webpage. It consists of a UI (the ascx) and codebehind. Cannot be reused in other projects by referencing a DLL.
WebControl: A control hosted on a webpage or in a UserControl. It consists of one or more classes, working in tandem, and is hosted on an aspx page or in a UserControl. WebControls don't have a UI "page" and must render their content directly. They can be reused in other applications by referencing their DLLs.
RenderedControl: Does not exist. May be synonymous to WebControl. Might indicate the control is written directly to the HttpResponse rather than rendered to an aspx page.
CompositeControl: Inbetween UserControls and WebControls. They code like UserControls, as they are composed of other controls. There is not any graphical UI for control compositing, and support for UI editing of CompositeControls must be coded by the control designer. Compositing is done in the codebehind. CompositeControls can be reused in other projects like WebControls.
You've forgotten the ServerControl.
In my understanding it is like that:
There are only two different kind of controls: UserControl and ServerControl
CompositeControls are kind of "advanced" UserControls. Find some more info on Scott Guthries Blog.
All of them are WebControls (because they are all derived from System.Web.UI.Control)
They are all rendered in any way so i would like to see them all as rendered controls.
From MSDN:
User Control
In ASP.NET: A server
control that is authored declaratively
using the same syntax as an ASP.NET
page and is saved as a text file with
an .ascx extension. User controls
allow page functionality to be
partitioned and reused. Upon first
request, the page framework parses a
user control into a class that derives
from System.Web.UI.UserControl and
compiles that class into an assembly,
which it reuses on subsequent
requests. User controls are easy to
develop due to their page-style
authoring and deployment without prior
compilation.
Server control
A server-side component
that encapsulates user interface and
related functionality. An ASP.NET
server control derives directly or
indirectly from the
System.Web.UI.Control class. The
superset of ASP.NET server controls
includes Web server controls, HTML
server controls, and ASP.NET mobile
controls. The page syntax for an
ASP.NET server control includes a
runat="server" attribute on the
control's tag. See also: HTML server
control, validation server controls,
Web server control.
Like Web Forms, user controls can be created in the visual designer or they can be written with code separate from the HTML. They can also support execution events. However, since Web user controls are compiled dynamically at run time they cannot be added to the Toolbox and they are represented by a simple placeholder when added to a page.
This makes Web user controls harder to use if you are accustomed to full Visual Studio .NET design-time support, including the Properties window and Design view previews. Also the only way to share the user control between applications is to put a separate copy in each application, which takes more maintenance if you make changes to the control.
Web custom controls are compiled code, which makes them easier to use but more difficult to create. Web custom controls must be authored in code. Once you have created the control you can add it to the Toolbox and display it in a visual designer with full Properties window support and all the other design-time features of ASP.NET server controls. In addition you can install a single copy of the Web custom control in the global assembly cache and share it between applications, which make maintenance easier.
Contrary to Will's response, it is possible to reuse UserControls in other projects by referencing a web deployment project.
Since I don't have enough reputation yet to comment, I'll add this as an answer, but it refers to Will's answer above.
From the link you included:
Composite controls are the right tool to architect complex components in which multiple child controls are aggregated and interact among themselves and with the outside world. Rendered controls are just right for read-only aggregation of controls in which the output doesn't include interactive elements such as drop-down or text boxes.
I believe the documentation is refering to UserControls that have been created by overriding the Render method as Rendered Controls. Thus, it is not a separate type as the question implies, but a way of implementing a UserControl; a pattern.

Resources