Accessing Grandparent Content Placeholder in Master Pages - asp.net

I've been searching the web and not finding any answers (there were a couple close questions on stack overflow but they didn't seem to get answered or be identical), so I thought I'd pose one of my own. It revolves around nested master pages and a content page accessing the Content PlaceHolder of the grandparent master even if it is not re-exposed in the parent nested master. I'm wondering if this is not possible.
Core Site.Master
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="TitleContent" runat="server">
<%= Html.GlobalModel().PageTitle %>
</asp:ContentPlaceHolder>
</title>
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
<link rel="shortcut icon"
href="<%= ViewContext.ClientContent( "Content/Tiki.ico" ) %>"
type="image/x-icon"/>
</asp:ContentPlaceHolder>
</head>
<body>
<asp:ContentPlaceHolder ID="SiteContent" runat="server"/>
</body>
</html>
Nested Site.Master (notice how TitleContent and HeadContent weren't customized, so the 'default' content from Core Site.Master should take affect)
<%# Master Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewMasterPage" %>
<asp:Content ContentPlaceHolderID="SiteContent" runat="server">
<asp:ContentPlaceHolder ID="SiteContent" runat="server">
<h1>Nested Header</h1>
<asp:ContentPlaceHolder ID="NestedContent" runat="server"/>
</asp:ContentPlaceHolder>
</asp:ContentPlaceHolder>
ContentView.aspx (referencing Nested Site.Master, the attempted TitleContent replacement will not work.)
<%# Page Language="C#" MasterPageFile="Site.Master" %>
<asp:Content ContentPlaceHolderID="NestedContent" runat="server">
<p>Nested content. This will work.</p>
</asp:Content>
<asp:Content ContentPlaceHolderID="TitleContent" runat="server">
Nested Title. This will **not** work.
</asp:Content>

ContentPlaceHolderIDs can only reference their immediate parent when listed declaratively.
The easiest fix, though not the most elegant, would be to copy the ContentPlaceHolders to Nested Site.Master with the same default code. Requires some code duplication, but gets the job done.
<%# Master Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewMasterPage" %>
<asp:Content ContentPlaceHolderID="TitleContent" runat="server">
<asp:ContentPlaceHolder ID="NestedTitleContent" runat="server">
<%= Html.GlobalModel().PageTitle %>
</asp:ContentPlaceHolder>
</asp:ContentPlaceHolder>
<asp:Content ContentPlaceHolderID="SiteContent" runat="server">
<asp:ContentPlaceHolder ID="SiteContent" runat="server">
<h1>Nested Header</h1>
<asp:ContentPlaceHolder ID="NestedContent" runat="server"/>
</asp:ContentPlaceHolder>
</asp:ContentPlaceHolder>
If you don't want to do that, you could replace the placeholders with custom controls that know what to show when.
Or if you need to keep it this way, you could run a bunch of code to force early rendering to an in-memory string/buffer and replace child controls with it — but that would be a ton of hassle, and it's doubtful if it would be worth the effort.
But any of those solutions depends on your situation. If you provided more context, we could provide more specific advise.

Related

Render master page element based on child page

In MVC one can use in _Layout.cshtml:
#if (IsSectionDefined("styles"))
{#RenderSection("styles", required: false)}
together with #Section styles on content page / layout to include css styles within <head> if given section is needed.
Is there an efficient way to mimic the same behaviour in Web Forms?
To summarise: I would like to have a possibility to render css and js on master page, only if they are required by specific child page based on that master page. So it will be not be included on pages which do not require those css and js files.
You could use ContentPlaceHolder. In your master page, define a content place holder as follows:
<head runat="server">
<title>..</title>
<meta charset="utf-8"/>
..
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
..and those child pages that require a special css or js files can use this content place holder to inject their needed files, e.g.:
<%# Page Title="" Language="C#" MasterPageFile=".." AutoEventWireup="true" CodeBehind=".." %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<link href="some css file dedicated only to this child page" rel="stylesheet" />
<script src="..js.."></script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
..
<h1><asp:Label ID="lblPageTitle" runat="server" Text=""></asp:Label></h1>
..
</asp:Content>

asp.net, showing the content of two contentplaceholder in different divs at the same time

I'm using asp.net, is there a way to show two contents of different aspx pages in parallel? (meaning showing each caontent, using contentplaceholder, in different div)
You can also achieve the requested functionality using the RadSplitter control and its ContentUrl property. See these demos for more information: http://demos.telerik.com/aspnet-ajax/splitter/examples/externalcontentloading/defaultcs.aspx and http://demos.telerik.com/aspnet-ajax/splitter/examples/showcontentduringload/defaultcs.aspx.
You can have multiple placeholders.
Example...
Site.Master
...
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
</asp:ContentPlaceHolder>
Default.aspx
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" runat="Server">

Events only firing on specific machines but not on others

I have been trying to solve this problem for several weeks now and it is getting really frustrating. Basically i have a simple project which includes one master page and one content page. the following code is what is found in the content page
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:Button ID="Button1" runat="server" Text="ButtonContent"
onclick="Button1_Click" />
</asp:Content>
The button is bound to a simple event. A break point is set to detect whether the event fired as expected. The event does not fire when a form is placed above the content place holder.
<%# Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<form></form>
</div>
<div>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
<div>
</div>
</form>
</body>
</html>
however the event is fired when the form is removed or place below the content place holder. On the other hand, on some machines i have found that it does not matter if a form is placed before the content place holder. I have tried this project on 4 machines (three windows 7 and one xp) it has worked regardless of form placement on two machines and has been subject to form placement on the other two.
Could some one please point me to some setting which could solve this problem or offer any advice to solve my problem. I need a form before the content place holder so removing is out of the question. It would also make sense that some sort of setting is preventing the project from working correctly on another machine
per HTML spec, you can not have form inside form. If I remember correctly some browsers break when you have this kind of structure. I think IE works fine.
If you need another form, put it outside of the <form id="form1" runat="server">
- above it, specifically. That is valid.

Asp.net Masterpage not working

<%# Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="stylesheet" type="text/css" href="Home.css" />
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
<div id="banner" style="font-family: Calibri, Serif; color: #FFFFFF">
blah blah
</div>
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
Home.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Home.aspx.cs" Inherits="Home"
MasterPageFile="~/MasterPage.master" Title="Welcome to StuartStudios!"%>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
</asp:Content>
Does Home.aspx not print whatever I define in the ContentPlaceHolder1 ? At the minute it prints nothing out. :S
When you specify markup in a ContentPlaceHolder inside of a MasterPage, that markup will only be rendered if the pages that use your master pages don't use the ContentPlaceHolder. So in Home.aspx, if you get rid of the Contact1 element, you should see your "banner" div.
So if you want your banner div to appear on ALL pages, you should move it to outside the ContentPlaceHolder control.
On your individual pages that use your master page, the Content tag should contain the stuff that's unique to the specific page.
No... ContentPlaceholder1 should be left blank in the masterpage.
I am no expert in ASP.Net, but as far as I understand the way <asp:ContentPlaceHolder /> works, when you add a <asp:Content> tag in your page file, you override the content of the ContentPlaceHolder in the master page. The contents of which will only be displayed if you do not have a corresponding Content tag.
Two things I see:
Your div in your master page has color set to white. So unless I'm mistaken, you're printing white on white.
Your Content item in Home.aspx IS empty, so why would it print anything else?

A different title in one page in ASP.NET MVC without creating another master page

In my master page I define the title of the page as follows:
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /><%= "- MyWebSite". %></title>
and then on every view I have something like:
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Products
</asp:Content>
so that I always end up with the name of the website in the title, like "Products - MyWebSite".
But for one and only one page, the home page, I want only the name of the site, as in "MyWebSite". Ideally I would like that for every view that doesn't define a title, I just show the name of the site. The problems is that with my current code I end up with "- MyWebSite" as title.
Any ideas how to do this without a lot of duplication? Definitely not creating another template.
You could put the - MyWebSite inside another ContentPlaceHolder, and make a Content control for it in the home page (only).
In the master page, you put something like
<title>
<asp:ContentPlaceHolder ID="TitleContent" runat="server" />
<asp:ContentPlaceHolder ID="TitleSuffixContent" runat="server">
- MyWebSite
</asp:ContentPlaceHolder>
</title>
and while your products page remain
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Products
</asp:Content>
your home page would be something like:
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
MyWebSite
</asp:Content>
<asp:Content ID="TitleSuffix" ContentPlaceHolderID="TitleSuffixContent" runat="server">
</asp:Content>
or even:
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
MyWebSite
</asp:Content>
<asp:Content ID="TitleSuffix" ContentPlaceHolderID="TitleSuffixContent" runat="server">
- Your place on the interwebs
</asp:Content>
what you need to do it's simply remove runat="server" attribute in your head tag

Resources