ASP.NET user control fails to render if registered with <%# Register Assembly="" (as opposed to Src="") - asp.net

I'm trying to create a user control and reference it on an aspx page. It works, but only if I reference the individual control, like this:
<%# Register TagPrefix="schmapp" TagName="TestControl" Src="~/TestControl.ascx" %>
instead of referencing the whole namespace, like this:
<%# Register Assembly="UserControlTest" Namespace="UserControlTest" TagPrefix="app" %> <!-- doesn't work-->
I've done this many times yet it's been a while so I might be forgetting something basic. I refreshed my memory with a few tutorials and I think I'm doing the same steps.
I had this in the project I'm working on (.NET 3.5 under VS 2008) and I reproduced it step by step in a very basic project (.NET 4 under VS 2010) - I uploaded it for reference purposes.
I create a new asp.net web project, then Add -> New Item -> Web User Control, and then type some text into the ascx file (just to check if the control is being rendered). I then register the control and try to add it on the page. It works if it's referenced by Src attribute:
<schmapp:TestControl runat="server"/>
but not if the whole assembly is being referenced:
<app:TestControl runat="server" />
Now I can list the controls one by one but it's ugly and I don't want to accept defeat by something so simple, so I summon the might powers of teh internets to help.

Related

Where is the code that runs when a button is clicked in ASP.NET

I'm trying to learn basic aspects of ASP.NET by analyzing the default Web Site project with Visual Studio 2010.
In the Register.aspx page there are fields for user registration and this button:
<asp:Button ID="CreateUserButton" runat="server" CommandName="MoveNext"
Text="Create User" ValidationGroup="RegisterUserValidationGroup"/>
The button does register an user, but I can't find the piece of code that is run and even less how code was associated to that button. I've tried searching the solution for all the identifier keywords and found nothing relevant. Searching on the web mentions a Button.OnClick method that I also can't find.
Any info on the basic aspects of ASP.NET will help me; thanks in advance.
Edit: hierarchically, the button is inside:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:CreateUserWizard ID="RegisterUser" runat="server" EnableViewState="false" OnCreatedUser="RegisterUser_CreatedUser">
<WizardSteps>
<asp:CreateUserWizardStep ID="RegisterUserWizardStep" runat="server">
<ContentTemplate>
<div class="accountInfo">
<p class="submitButton">
There is a RegisterUser_CreatedUser method on the code behind and it does:
protected void RegisterUser_CreatedUser(object sender, EventArgs e)
{
FormsAuthentication.SetAuthCookie(RegisterUser.UserName, false /* createPersistentCookie */);
string continueUrl = RegisterUser.ContinueDestinationPageUrl;
if (String.IsNullOrEmpty(continueUrl))
{
continueUrl = "~/";
}
Response.Redirect(continueUrl);
}
I was expecting some kind of inserting of user data on a database. I wonder, is this all that the button does?
The button you are looking it should be in CreateUserWizardStep control. I don't know much about this control but probably control looks for a child button having CommandName = "MoveNext", then it hooks for its click event.
Try changing the CommandName to something else like "test", it should NOT hit the breakpoint on RegisterUser_CreatedUser event.
Also note that CreatedUser <- event is telling that user is created, now the rest of the code is just authenticating the same user. Behind that, the user is already been created and saved in database.
If you also look in the web.config you will find this ConnectionString
<connectionStrings>
<add name="ApplicationServices"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
Since you are using the Visual Studio's Default Web Application project, these all things are already done by Visual Studio for you.
An aspx page will also have a "code behind" file with the same name but a different extension (the letters after the dot) which depends on the language it's written in. Visual basic files have a .vb extension while C# files have a .cs extension.
Try looking for Register.vb or Register.cs and see if that's more fruitful.
If you're using a development environment like Visual Studio, you'll probably find that in the Solution Explorer you can click to expand the aspx file and see its code behind file underneath. If you're not, you might want to pick up a copy of the free express edition:
http://www.visualstudio.com/en-US/products/visual-studio-express-vs
When you find the code-behind, look for method called "MoveNext" - that's the code that'll run when you click the button, as specified by the CommandName attribute of the asp: Tag.
You've complicated a couple of things and you are completely not at fault but partly the project templates which comes with VS 2010 IDE. Let me try to help you one by one:
Learning basics of ASP.Net : For this you should be using "ASP.NET Empty Web Application" project template present in Visual Studio 2010. You've started with "ASP.NET Web Application" project template which has complicated things for
you. To start afresh "ASP.NET Web Application" looks the obvious choice for anyone though but it comes with a precooked boiler-plate code meant for ASP.NET membership forms authentication and its associated controls which is the root cause of all your confusion. To get started with the basics take the "ASP.NET Empty Web Application" project template I've suggested above and then add a new "Web Form" and then add various basic server web controls like button or text box to get started with concepts like event handling and code behind stuff.
Your other problem -
"The button does register an user, but I can't find the piece of code
that is run and even less how code was associated to that button"
That is because the button that you are seeing on Register.aspx page is
NOT an individual server web control but it is part of a composite control asp:CreateUserWizard instead. All the events of various controls be it a button, label or text box which are part of the asp:CreateUserWizard composite control is handled by the parent composite control asp:CreateUserWizard. You will NOT find all that code in your code behind file as this is present in System.Web.dll which is referenced in your project.
Since all the control events present on the composite control are handled by a common function written inside the code of composite control it has to distinguish exactly which control was clicked by the user (to take an appropriate action) which caused the current page post back for which CommandName property comes into picture. There is a switch case statement inside that common function for parent composite control which uses the CommandName property.
So essentially what happened is when you tried to start understanding basics of ASP.Net server web controls and event handling you actually got into the path of understanding ASP.Net Membership & role web server controls & providers which might be comparatively tough to understand and grasp initially. Hope this helps you to get started and further your understanding on ASP.Net world.

How to force update .ascx file content in Website project

I have Website project, which contains some .ascx and .aspx files. I have added new element <asp:TextBox ID="tb1" runat="server" ... /> in .ascx file and I have wrote some code in proper .ascx.cs file using this element: tb1.Text = "SomeText";. When I compile this project I recieve following error: The name 'tb1' does not exist in the current context.
How can I force to refresh markup of .ascx page? I use Website project and I cannot to change its type to Webapplication.
UPD: I have Website project, which has NOT .ascx.designers.cs files. And I cannot change type of my project to web application.
Unless there's something else happening here, it sounds like the designer.cs file might be out of sync. Try cutting and pasting the control back into the markup, or go into the designer file for the user control and add the TextBox manually:
protected global::System.Web.UI.WebControls.TextBox tb1;
It seems like your design file is not connecting with your code behind file.
Can you confirm if you are defining it as follows,
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="yourcontrol.ascx.cs" Inherits="CompleteNameSpace.ClassName" %>

Html helpers (from asp.net mvc) in webpages

Is it possible to use MVC Helpers in webpages (cshtml) ?
I'm trying out some controls from infragistics, and would like to use the html helper method to create the grid (avoiding some javascript) but I can't seem to get any intellisense.
No, I'm unsure if it should work?
Update: I want to use the following line:
#Html.Infragistics().Grid(....
inside my MyWebPagesPage.cshtml
Thanks for any help
Larsi
You should be able to, just add
#using infrajistics.namespace
You could also add the namespace to ur web.config namespaces section so that you don't have to add the #using in each view
There are no helper method that would render Infragistics controls. Please take a look at this page, it has detailed instructions of using Infragistics controls in MVC pages.
There are some limitations though. Infragistics doesn't have separate controls for MVC, they are simply making their asp.net controls available, but there's a drawback.
As long as you focus on areas of the controls that do not initiate post backs or rely on ViewState, you soon find many behaviors and functions that work perfectly in an ASP.NET MVC application.
Sample usage would be:
<%# Register Assembly="Infragistics.Web.Mvc" Namespace="Infragistics.Web.Mvc" TagPrefix="cc1" %>
<%# Register Assembly="Infragistics35.Web.v9.1, Version=9.1.20091.1015, Culture=neutral, PublicKeyToken=7dd5c3163f2cd0cb"
Namespace="Infragistics.Web.UI.GridControls" TagPrefix="ig" %>
<ig:WebDataGrid ID="wdg"
runat="server" Width="50%"
EnableViewState="false">
</ig:WebDataGrid>
No MVC helpers involved.

Register User Control Issue

I have a user control registered at the top of my page:
<%# Register Src="/Controls/User/Navbar.ascx" TagName="Navbar" TagPrefix="pmc" %>
and I reference it in my page like this:
<pmc:Navbar runat="server" id="navbar"></pmc:Navbar>
but it does not know what <pmc:Navbar is. I cannot figure out why.
I'm using VS 2008, in a Web Application Project.
Maybe you should specify the path with ~: ... Src="~/Controls/User/Navbar.ascx" ...
Remove either the initial slash from the path to the control, or better still, prefix it with "~" :
<%# Register Src="Controls/User/Navbar.ascx" TagName="Navbar" TagPrefix="pmc" %>
or
<%# Register Src="~/Controls/User/Navbar.ascx" TagName="Navbar" TagPrefix="pmc" %>
The first solution is flakey as it relies on the page existing in the root folder and the control existing below it. The second is the preferred as it will work from any page in your project.
You should also consider registering your user controls in your web.config, as it keeps things much neater, and tends to avoid path issues a little better.

Strongly-typed ASCX in WebForms 3.5?

I'm looking to get rid of the code-behind for a control in my WebForms 3.5 application. Again bitten by the bug of how it's done in MVC, I'd like to get a step closer to this methodology by doing:
<%# Control Language="C#" Inherits="Core.DataTemplate<Models.NewsArticle>" %>
This gives me the parser error you'd expect, so I remembered back to when this was an issue awaiting a fix in the MVC Preview, and changed it to:
<%# Control Language="C#" Inherits="Core.DataTemplate`1[[Models.NewsArticle]]" %>
But this doesn't work either! How is it that the MVC team were able to harness this ability? Was it something special about the MVC project type rather than the latest VS2008 Service Pack?
Short of giving up and requiring future templates to have code-behind files, what are my best options to get this as close to the generic user control method as possible?
Well, it appears like I've managed to do it. After looking at the PageParserFilter implemented by the MVC team for ViewUserControl<T>, I was able to construct something similar for my own DataTemplate<T> purposes. Sweet. I can now use the line:
<%# Control Language="C#" Inherits="Core.DataTemplate<Models.NewsArticle>" %>
And, without any code behind file, it parses! I'll report back if I find that I've broken something else in the process!
With WebForms you lose pretty much everything that makes them useful without a code behind page, because then VS can't auto generate the designer file that holds the actual definitions for all your runat="server" controls.
What you can do is have a common base page class, and make that generic:
public class DataTemplate<T> : Page {
public T Model {get;set;}
}
public partial class MyCodeBehindClass :
DataTemplate<Models.NewsArticle> {
...
}
This would allow all the drag-drop component stuff that WebForms does to work unhindered, while also allowing you to access a strongly typed model on the page:
<%# Control Language="C#" Inherits="MyCodeBehindClass" %>
<% foreach( var item in Model ) { %>
<!-- do stuff -->
<% } %>

Resources