Access body element from content page via a nested master page - asp.net

All I want to do is access the <body> element from the code-behind of a content page and add a class name to it.
I have a top-level master page with the <body> element in it. Then I have a nested master page which is the master page for the content page. From the code behind of the content page I want to add a class name to the body element. That's all.
I have this in the top-level master:
<body id="bodyNode" runat="server">
I added this to the code-behind for the content page:
Master.bodyNode.Attributes.add("class", "home-page");
And I get a message that:
System.Web.UI.MasterPage' does not contain a definition for 'bodyNode
If I add this to the aspx content page:
<% # MasterType VirtualPath="~/MasterPage.master"%>
The message then changes to:
bodyNode is inaccessible due to its protection level
Please advise, I've wasted like 2 hours on what feels like something that should be really simple to do :(

once you have set runat="server" for your body node, you have to access it using the HTMLControls namespace. try this.
public void Page_Load(Object sender, EventArgs e)
{
//Inject onload and unload
HtmlGenericControl body = (HtmlGenericControl)Master.FindControl("bodyNode");
body.Attributes.Add("class", "home-page");
}
EDIT
Your problem is that you have nested master pages.
Since the "body" tag is in your top level master page, Master.FindControl() won't work, as that is looking in the nested master page.
What you need to do is use Master.Master.FindControl(), or recursively loop through your master pages, going up until Master.Master is null (as then you know you are at the top level master page) and then calling FindControl() on that.

I would add a public property to the code behind of the master page that would allow access to the body tag that is part of the master page. And then call that property from the content page.

Related

Aspx file in two master pages

I have a page on a website that uses a master page and a child page. I would like to use the child page to create a new page on the website, but with a different master page.
Is it possible to do this without duplicating the code for the child page?
To make it clearer I have also added a link to a picture of the layouts used for the two pages.
In the picture, both children use the same code.
Edit: I have also thought about using a control for this, but I am not sure if this is the proper solution. The child page is pretty big and complex and also uses a lot of JavaScript.
When loading the child page, you can set the master page dynamically in code, in the PreInit event. Something like this:
void Page_PreInit(Object sender, EventArgs e)
{
this.MasterPageFile = "~/NewMaster.master";
}
That way your child page can set its master page based on whatever condition you would have in your site.

How to access span tag which is on the master page from content page's code behind?

I have written the code in ASP.NET AJAX to authenticate and authorize the user.
Now, if the user role doesn't have permission to access certain resource, then at login time only I want to show some message in one span tag which is on the master page. I want to do This from contnet page only.
Hence how can I access the span tag which is on the master page from content page's code behind.
I cannot use runat="server" for my span tag, why because, it is affecting the existing code.
Correct way is to expose a public property (say Message) in master page for capturing the message. In master markup, you can use it within span such as
<span><%= this.Message %></span>
In content page, cast the master page to master's code-behind class and set the property to whatever value you wish:
((MyMaster)this.Master).Message = "bla bla...";

Output cache in content and master page

Two questions:
1. If I have a content page and a master page and I put this inside my content page:
<%# OutputCache ...%>
Does it cache the whole page or only the content page portion?
2. How can I apply OutputChace in the master page?
I have a master page that has a lot of content pages that uses it. I want to apply the same outputcache profile on all of them, but I dont want to go one by one and change them.
Thanks.
The whole page is cached.
Edit
You can use user controls to cache portions.
As by the comments, if you want to cache all pages that are using a specific master page, you need the following code in the master page
protected void Page_Load(object sender, EventArgs e)
{
Response.Cache.SetExpires(DateTime.Now.AddMonths(1));
Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate);
Response.Cache.SetValidUntilExpires(true);
}
Content page only will be cached; unless that content page is using the master page, in which case master page also will be cached.
Unlike a content page you can't use OutputCache directive for master page. See the below links
Cache Master Page in ASP.NET
http://www.dotnetperls.com/output-cache
http://forums.asp.net/t/1236981.aspx

How does one get a code-behind file to recognize type of a user control?

I have a custom control in my mater page that represents a menu, let's call it CustomMenu. The control code files are located in a non special directory.
I want to give each page that uses that master page the ability to access the control and, using a public property, tell the control whether or not it should render itself.
I have a public property on the control to do that, and I know I can get the control by referencing Page.Master.FindControl('IdOfControlIwant');
The problem I'm having is that I can't seem to get the control Type recognized by the compiler, so when I do find the menu control, I can't actually work with it. The only way I can get the code behind to recognize the type is to register it in the ascx file, and then add at least one control to the page, which is undesirable.
Thoughts?
You have to combine what both Jacob and dzendras have posted. Add the MasterType directive to your content page's aspx file:
<%# MasterType VirtualPath="~/your.master" %>
And in the master page create a property:
public CustomMenu MyCustomMenu {get{ return myCustomMenu;}}
Where myCustomeMenu is the ID of the Usercontrol in your masterpage.
You should now be able to reference the usercontrol from a content page. So, if the CustomMenu usercontrol had a property called SelectedItem, you should be able to access it like this:
public void Page_Load(object o, EventArgs e)
{
Master.MyCustomMenu.SelectedItem = 1;
}
Use the MasterType directive in your pages:
<%# MasterType VirtualPath="~/your.master" %>
That will strongly type your Master page reference, so you should be able to add properties that can be accessed by the pages.
Make a property of your MasterPage class:
bool IsCustomMenuVisible {set{ CustomMenu.Visible = value;}}
And use it wherever you like.

event of asp.net master page not firing

I put a break point at the protected void Page_Load(object sender, EventArgs e) method of my master page, but when i start the site it does not hit that break point.
Why is the event not firing? I would like to use this event along with others such as the Init event in order to check to see if the session has expired everytime a page loads...
Thanks.
You can check that AutoEventWireup is set to true in the Master declaration.
<%# Master Language="C#" MasterPageFile="~/MasterPages/Main.master" AutoEventWireup="true" CodeFile="Main.master.cs" Inherits="MasterPages_Main" %>
If it is set to false you have to manually connect the events.
The problem is likely that your .aspx page has not correctly referencing your .master page. Be sure that, at the top of your .aspx page, you have a line similar to the following:
<%# Page Title="Some Title" Language="C#" MasterPageFile="Main.Master" CodeBehind="MyPage.aspx.cs" Inherits="MyApp.MyPage" %>
Another possible problem is that your .master page isn't referencing the proper (or any) assembly. Be sure that the top line of your .master page is similar to the following:
<%# Master Language="C#" AutoEventWireup="True" CodeBehind="Main.master.cs" Inherits="MyApp.Main" %>
A couple of things to check, some of which may be obvious...
Check your child page is calling the correct Master Page.
The Master Page Page_Load executes after the child Page_Load, so make sure you debug through the child page execution first.
Check that you've actually got your Page_Load event wired up if you're using VB.NET.
You might want to try creating a base class of type Page that handles your session check. Leave the master pages for page design. If you have multiple master pages, you would have to duplicate that code in each one, but if your pages inherit from a single base page, your session check logic will be in one place.
I had the same problem - the pageload was firing before but something went wrong and it stopped.
What fixed it was putting the page_load event in the .master file not the .master.cs
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
//put your code here
//any function u wanna call declare it in the code file as public
}
</script>
I had a slightly different problem and different solution.
Just in case anyone has similar situation as me.
I had a nested master page and the control and related event method were in the "middle" master. The methods did NOT get called when they were placed in .cs file for middle master page. But they got called when included in .master page within script tags as described above by "petra".
This seems to be more of a bug in .net platform - Also - I do not think some of the above complicated solutions are (or should be) needed (e.g., keeping code out of master page and using master page only for structure etc.) - that is more of a workaround and I suspect there indeed is a bug in .net platform with respect to master page event firings (specially with nested master pages as in my case).
You need to check declaration of page to make sure it refers proper masterpage and masterpage, to make sure that it refers proper inherited class.
My error occured because of comment line >>> base.OnLoad(e); in Site.Master.cs
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
PEACE

Resources