I'm embarrassed to ask this here because it's clearly been duplicated several times already on StackOverflow. I've read a lot of stuff including:
http://msdn.microsoft.com/en-us/library/xxwa0ff0
http://msdn.microsoft.com/en-us/library/c8y19k6h.aspx
http://www.velocityreviews.com/forums/t110056-cannot-access-strongly-typed-properties-in-master-page.html
I think I've done exactly what those article say, but it's not working for me.
Here's the top of my master page, named "MasterNoNews.master":
<%# Master Language="C#" %>
<%# Import Namespace="MyMediHealth.DataAccess" %>
<%# Import Namespace="MyMediHealth.DataAccess.Containers" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
public virtual UserContainer CurrentUser;
protected void Page_Load(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
CurrentUser = new MembershipQueries().getUserFromUserIdName(Page.User.Identity.Name);
}
</script>
Here's the top of my child page, named "MyProfile.aspx":
<%# Page Title="" Language="C#" MasterPageFile="~/MasterNoNews.master"
AutoEventWireup="true" CodeBehind="MyProfile.aspx.cs"
Inherits="MyMediHealth.Interface.MyProfile" %>
<%# MasterType VirtualPath="~/MasterNoNews.master" %>
Here's the code-behind on my child page, named "MyProfile.aspx.cs" that's not working:
using System;
using System.Web.UI;
using MyMediHealth.DataAccess.Containers;
using MyMediHealth.DataAccess;
namespace MyMediHealth.Interface
{
public partial class MyProfile : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// doesn't work
UserContainer user = Master.CurrentUser;
// also doesn't work
UserContainer user = ((MasterNoNews)this.Master).CurrentUser
}
}
}
In the first case, VS is telling me System.Web.Ui.MasterPage does not contain a definition for CurrentUser. In the second case, VS says the type or namespace 'MasterNoNews' could not be found.
What am I doing wrong?
You'll probably still need to move the master page's code to the code behind, but if you put this,
<%# MasterType VirtualPath="~/MasterPages/Site.master" %>
on the aspx page you'll be able to access the master page's public methods directly without all that casting. Like so:
UserContainer user = Page.Master.CurrentUser
If you're using the master page's code from loads of child pages then I'd create an interface and have the master page implement it.
This will not work because you have created properties within Master page (and not code-behind). Typically, master page code would get compiled dynamically and a class name (depending on file name) will be created in a temporary assembly. As you are not reffering to this generated class name within temp assembly, you get error. Correct way will be to have code behind file for the master. For example, master will be
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="MasterNoNews.master.cs" Inherits="[Your Namespace].MasterNoNews" %>
And in code-behind file (MasterNoNews.master.cs) have your properties:
namespace [Your Namespace]
{
public partial class MasterNoNews : System.Web.UI.MasterPage
{
public virtual UserContainer CurrentUser;
protected void Page_Load(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
CurrentUser = new MembershipQueries().getUserFromUserIdName(Page.User.Identity.Name);
}
}
}
Now the second syntax would work i.e.
UserContainer user = (([Your Namespace].MasterNoNews)this.Master).CurrentUser
Related
I'm currently on my first asp.net WebForms Site. To display different Sites I'm loading a control into a Placeholder in my masterpage.
example: UserControl uc = this.LoadControl("~/controls/home.ascx") as UserControl;
this goes over my default.aspx codebehind file. I'm now struggeling with fill in another control based on the URL. I know that you can get for example an ID (if my-domain.com/default.aspx?id=1 then show control blabla) but is it possible that I read out the URL and instead of the ID a string? for examples:
my-domain.com/home -> this goes over my default.aspx, but shows de home controller
my-domain.com/contact-> this goes over my default.aspx, but shows de contact controller
Can I check if it's "/home" and then show the home-control?
Has anyone an idea, how I could solve this problem?
Thanks guys :)
Here are a few code snippets:
masterpage.master:
<asp:ContentPlaceHolder id="content" runat="server"></asp:ContentPlaceHolder>
default.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/masterpage.master" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="myproject._default" %>
default.aspx.cs:
public partial class _default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ContentPlaceHolder content = this.Master.FindControl("content") as ContentPlaceHolder;
displayControl(content);
}
private void displayControl(ContentPlaceHolder content)
{
UserControl uc = this.LoadControl("~/controls/home.ascx") as UserControl;
if ((content != null) && (uc != null))
{
content.Controls.Add(uc);
}
}
}
home.ascx:
my HTML-Page
My folders are in the following structure:
css
img
javascript
App_Data
bin
obj
controls
home.aspx
contact.aspx ... etc.
default.aspx (with the code behind file .cs)
masterpage.master
misc: web.config and other files and folders...
If you want your site to go from domain.com/default.aspx?id=1 to domain.com/home, or domain.com/login you need to enable Friendly URLs and setup a route in your WebForms.
Scott Hanselman has a walk-through at the following link...
http://www.hanselman.com/blog/IntroducingASPNETFriendlyUrlsCleanerURLsEasierRoutingAndMobileViewsForASPNETWebForms.aspx
I'm creating a website which allows users to log in. After logging in successfully, user's name should be displayed across each page, for example, at the top right corner. I have a ContentPlaceHolder on Master Page. An h3 tag would then be created and added into this ContentPlaceHolder.
Master Page:
<asp:ContentPlaceHolder runat="server" ID="UserNamePlaceHolder">
</asp:ContentPlaceHolder>
Login Page:
<%# MasterType VirtualPath="~/Master" %>
Login Class:
protected void Login_LoggedIn(object sender, EventArgs e)
{
ContentPlaceHolder userNamePlaceHolder =
(ContentPlaceHolder)Master.FindControl("UserNamePlaceHolder");
var h3 = new HtmlGenericControl("h3");
h3.InnerHtml = login.UserName;
userNamePlaceHolder.Controls.Add(h3);
}
I did debugging step by step. Nothing went wrong: no null or empty value, each variable was created. However, the user name was not displayed at all. Does anyone have an idea?
A cleaner and better approach would be to create a public property on the Master page:
public string UserName
{
get
{
return Literal1.Text;
}
set
{
Literal1.Text = value;
}
}
That's it place the literal with ID Literal1 anywhere you want on the master page:
<asp:Literal runat="server" ID="Literal1" />
You are already adding Master directive for strongly typing Master class, so now your login class would look like this:
protected void Login_LoggedIn(object sender, EventArgs e)
{
Master.UserName = login.UserName;
userNamePlaceHolder.Controls.Add(h3);
}
Hope this helps.
I saw on several web pages how to interface to a public method defined in a master file from a web page call behind code that uses that master file.
(I am using ASP.Net 4.0 on Visual Studio 2012.)
The procedure is (copied from article):
Make sure the function is accessible to the page (i.e. declared
public), and use the MasterType declaration in the ContentPage:
<%# Page .... %>
<%# MasterType VirtualPath="~/masterpage.master" %>
In the page, use Page.Master.MyFunction() to access the function.
*Note: before being able to access the function, you'll need to save & build.
The problem is that I do not see the method. Here is what I have:
Web Page (stored in /MyFolder, so /MyFolder):
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Logout.aspx.cs" Inherits="BvCorpMain.Candidates.Logout" %>
<%# MasterType VirtualPath="/SiteMasters/Site.Master" %>
Site.Master CS file (stored in /SiteMasters folder):
public void UpdateUserBlocksToCookie()
{
}
When I go into the code behind for the logout page and in a method I type in "Page.Master.", I do not see my method.
Your page is inheriting from System.Web.UI.Page, which only knows that its master page is of type System.Web.UI.MasterPage. If you are making modifications to a child class of MasterPage, then you need to cast the Page.Master property to your child class.
public class MyPage : System.Web.UI.Page
{
public new MyMaster Master { get { return base.Master as MyMaster; } }
public void Page_Load(object sender, EventArgs e)
{
Master.MyMasterPageFunction();
}
}
public class MyMaster : System.Web.UI.MasterPage
{
public void MyMasterPageFunction()
{
}
}
The previous answer did educate me, however I believe the resolution was to restart VS2012, maybe cleaning the solution and rebuilding did not hurt. Either way.
Microsoft adds in the following code automatically to the .aspx.designer.cs file.
/// <summary>
/// Master property.
/// </summary>
/// <remarks>
/// Auto-generated property.
/// </remarks>
public new MyNamespace.Site Master {
get {
return ((BvCorpMain.Site)(base.Master));
}
The previous answer conflicts with this definition. Also, the previous answer of MyMaster, although granting access does not give (automatically at least) to needed form information. I checked. Using the existing master file is the cleanest.
The definition for the master.cs file is:
namespace MyNamespace
{
public partial class Site : System.Web.UI.MasterPage
As you can see, Microsoft did give access to MyNamespace.Site, which is what I needed, with "Master.".
I did not think to check the .aspx.designer.cs file for that definition, when I was having the problems. Possibly the definition was lacking and got added later, when either I rebuilt or did a save, which I had previously done, or whatever.
Knowing the addition does simplify things, as I can add that in manually if it does not exist using that construct.
Page does't show code behind code when clicking on Design code and also code behind code display error as control not found
Below code display error : System Error
<%#Page Language="C#" AutoEventWireup="true" CodeFile="Register.aspx.cs" Inherits="Register" %>
I don't why it fetches this type of error ,please help me
Code Behind:
using System;
The only reason for which the designer cannot open the code behind is because it cannot find the associated code behind file specified Inherits="Register"
Make sure you have a public class named Register that must be Partial as well
make sure also the the code behind file name is named as Register.aspx.cs
must check make Inherits attributed in design and code file path
Ok, I totally misunderstood your question.
If your Register.aspx file looks like this:
<%#Page Language="C#" AutoEventWireup="true" CodeFile="Register.aspx.cs" Inherits="Register" %>
The Register.aspx.cs should look (at least) like this:
using System;
namespace YourDefaultNamespace
{
public partial class Register : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
I notice that you don't have a namespace in the Inherits attribute of your <%# Page %> directive. It should have the same namespace as your codebehind file. In my example that's YourDefaultNamespace, so my <%# Page %> directive should be this:
<%#Page Language="C#" AutoEventWireup="true" CodeFile="Register.aspx.cs" Inherits="YourDefaultNamespace.Register" %>
I am trying to dynamically load a user control in an asp.web site. However due to how asp.net websites projects are setup (I think), I am not able to access reach the type definition of the user control.
I get a message saying that my class HE_ContentTop_WebControl1 is: he type or namespace name 'HE_ContentTop_WebControl1' could not be found (are you missing a using directive or an assembly reference?)
Any idea how this could be made to work ? I have attempted using namespace but it seems to me that asp.net websites are not designed to work with namespaces by default. I would be interested in a non namespace approach.
TIA
public partial class HE_Default :
System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e)
{
var control = (HE_ContentTop_WebControl1)Page.LoadControl("~/ContentTop/WebControl1.ascx");
}
}
Assuming the control exists in the same assembly as your web project, you need to add a reference directive in your .aspx file,
e.g:
<%# Reference Control="~/Controls/WebControl1.ascx">
Keep in mind it often takes a few minutes (or sometimes a build) for IntelliSense to pick this up.
It can easily be done using namespaces. Here's an example:
WebControl1.ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="WebControl1.ascx.cs" Inherits="MyUserControls.WebControl1" %>
Notice that Inherits references the namespace (MyUserControls), and not just the class name (WebControl1)
WebControl1.ascx.cs:
namespace MyUserControls
{
public partial class WebControl1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
Notice that the class have been included in the namespace MyUserControls
Default.aspx.cs:
using MyUserControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var control = (WebControl1) Page.LoadControl("~/WebControl1.ascx");
}
}
This approach potentially allow you to redistribute your user controls (or keep them in a separate project) without the hassle of referencing them in your .aspx files.
Namespaces are not supported under the website model. As such, I could not get any of the solutions proposed to work. However, there is a solution. Create an interface and place it into app code and then implement the interface in the user control. You can cast to the interface and it works.
The subject of this post is a bit misleading. If you just want to add a control dynamically, you will not have to reference the control and therefore you can just add it with something simple like:
protected void Page_Load(object sender, EventArgs e)
{
Page.Controls.Add(Page.LoadControl("~/MyControl.ascx"));
}
without any namespace hassel.
the reference is not enough using
<%# Reference Control="~/Controls/WebControl1.ascx">
in the aspx file is just one part of the answer.
you need also to add the calssName in the User Control aspx file
<%# Control ClassName="WebControl1" Language="C#" AutoEventWireup="true" CodeFile="WebControl1.ascx.cs" Inherits="AnySpaceName.DateSelector" %>
and then you can use the userontrol in your aspx file
AnySpaceName.WebControl1 WC = (AnySpaceName.WebControl1)Page.LoadControl("~/WebControl1.ascx");
Casting the user control this way may create many problems .my approach is to create a class (say control Class) put all the properties and method you need for casting in it and inherit this class from System.Web.UI.UserControl .Then in your user cotrol code file instead of System.Web.UI.UserControl user this control class .
now when ever you need casting, cast with this class only . it will be light casting as well.