How to resolve Cannot find ContentPlaceHolder error? - asp.net

Having a "duh" moment trying to implement a new content page
Here's the structure
Master Page
---- Nested Master Page
-------- Nested Master's Content Page
Mark up:
Master Page
<asp:ContentPlaceHolder ID="bodyContent" runat="server">
</asp:ContentPlaceHolder>
Nested Master Page
MasterPageFile="~/Views/Shared/Administrator.Master"
<asp:Content ID="Content2" CotentPlaceHolderID="bodyContent" runat="server">
</asp:Content>
Nested Master's Content Page
MasterPageFile="~/Views/Intervention/InterventionMaster.master"
<asp:Content runat="server" ID="myContent" ContentPlaceHolderID="Content2">
</asp:Content>
Receive error:
Cannot find ContentPlaceHolder 'Content2' in the master page
'/Views/Intervention/InterventionMaster.master', verify content
control's ContentPlaceHolderID attribute in the content page.
What could I be doing wrong?

You don't have ContentPlaceHolder with ID = "Content2". You have only content with such ID. Put another placeholder inside of content with ID="Content2" and then connect with the page content.
Master Page
<asp:ContentPlaceHolder ID="bodyContent" runat="server">
</asp:ContentPlaceHolder>
Nested Master Page
<asp:Content ID="Content2" ContentPlaceHolderID="bodyContent" runat="server">
<asp:ContentPlaceHolder ID="nestedContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
Nested Master's Content Page
<asp:Content runat="server" ID="myContent" ContentPlaceHolderID="nestedContent">
</asp:Content>

A dirty-quick solution would be to bypass the Nested Master Page
from the Nested Master's Content Page
protected void Page_PreInit(object sender, EventArgs e)
{
Master.MasterPageFile = "~/Whatever.Master";
}

Use ID="MainContent"
<asp:Content ID="Content2" ContentPlaceHolder ID="MainContent" runat="server"></asp:Content>

Codeone was close, try using
<asp:Content ContentPlaceHolderID="MainContent" runat="server">

Related

Overriding css Style on aspx page with master page

I have a aspx web page using a master page.
There is a style.css sheet which is a global style.
How can I override the style for all the content in the aspx page, but not alter anything else?
so for example something like this in the aspx page
<asp:Content overridestyle = true>
...
</asp:Content>
EDIT
I found something that sort of sort of works, but it removes the style for the entire page, including the content on the masterpage. Is there anyway to do this solution but only for the content in the contentplaceholder?
new protected void Page_PreInit(object sender, EventArgs e)
{
Page.Theme = "";
}
Add the Content place holder in the master page like this under section
<head runat="server">
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"></asp:ContentPlaceHolder>
</head>
in your aspx page,
<asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<link href="*****style sheet path****" rel="stylesheet" type="text/css" />
</asp:Content>

Access master page control from usercontrol of aspx which enclosed in master page

I have a aspx page which enclosed in master page. My aspx page have user control (ASCX) from user control I am opening a pop up in which I want to get master page controls how can I do it.
ASP.NET has internal property for each page 'Master'. From usercontrol you can travese the stack backwards to Usercontrols parent > Page > Master. If the control in master page is outside any contentplace holders, you can get the control using FindControl method. If it is inside any content place holders, you have to traverse to the content place holder and then you can find the control. The example is below.
MASTER
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblVal" runat="server" Text="MasterLabel"></asp:Label>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
CONTENT PAGE
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<test:uc ID="test" runat="server" />
</asp:Content>
USER CONTROL
<%# Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
USERCONTROL CODE BEHIND
protected void Page_Load(object sender, EventArgs e)
{
MasterPage mstr = this.Parent.Page.Master as MasterPage;
Label1.Text = (mstr.FindControl("lblVal") as Label).Text;
}
In my case the Label in master page is outside content page.

Access to MVC Models from standard ASCX UserControl

I've got a simple ASCX user control (non-MVC). The user control has a property on it (let's call it Title or something).
I've also got an MVC Partial View which contains the user control.
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SomeModel>" %>
<%# Register TagPrefix="tag" TagName="Control" Src="~/path/to/ascx/control.ascx" %>
... snip ...
<tag:Control ID="myControl" runat="server" />
What I'd like to be able to do is something like this:
<tag:Control ID="myControl" runat="server" Title="<%= Model.Title %>" />
... so that I can access some property of the model inside my Control.
Unfortunately this method doesn't work, as I get a message saying "This is not scriptlet. Will be output as plain text".
Is what I'm trying to do even possible? If so, does anyone have any ideas how I can try and do it?
If it's relevant, this is a .Net 4 project, with MVC 2 components.
Thanks!
Neil
Is what I'm trying to do even possible?
Yes but it would be extremely ugly and it involves using a code behind (in an ASP.NET MVC view!!!):
<%# Page
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="AppName.Views.Home.Index"
CodeBehind="Index.aspx.cs"
%>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:Label ID="Txt" runat="server" />
</asp:Content>
and in the corresponding code behind Index.aspx.cs (beurk..., I will vomit):
public partial class Index : System.Web.Mvc.ViewPage<AppName.Models.MyViewModel>
{
protected void Page_Load(object sender, EventArgs e)
{
Txt.Text = Model.Title;
}
}
which could be improved like this to avoid the code behind nonsense:
<%# Page
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<AppName.Models.MyViewModel>"
%>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Txt.Text = Model.Title;
}
</script>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:Label ID="Txt" runat="server" />
</asp:Content>
I wouldn't recommend you doing something like this if you intend to migrate to ASP.NET MVC 3 and the Razor view engine one day.
I found a solution that's a little cleaner. Still not to my liking, but good enough to wash my hands of this annoying issue.
<% ViewBag.Item = item; %>
<gc:Ribbon runat="server">
<Content>
<strong><%= ViewBag.Item.DataItem.Name %></strong>
</Content>
</gc:Ribbon>
Instead of passing an object into the user control to use within, assign it to the ViewBag (for each iteration if you're looping), and use it globally. If memory serves me right, I believe MVC 2 uses ViewData["loosely typed name"] instead of the dynamic ViewBag.

Content control not accessbile from content page?

My content page looks like this:
<%# Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Basket.aspx.cs" Inherits="Basket" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
</asp:Content>
Now, I would like to add some controls dynamically to the content when page loads, so I am trying the following code:
protected void Page_Load(object sender, EventArgs e)
{
Content2. // I want to add controls to it dynamically
}
The problem is that the Content2 control is not visible by the compiler and I am getting error about missing directive or assembly reference.
Any solution?
The reason you can't get a reference to that asp:Content control is because it does not stay around when the page is combined with the masterpage. Basically ASP takes all the controls from inside these asp:Content sections and makes them children of the ContentPlaceholder controls inside the masterpage.
As MSDN says: A Content control is not added to the control hierarchy at runtime. Instead, the contents within the Content control are directly merged into the corresponding ContentPlaceHolder control.
That means that if you want to add more controls to that section, you will have to get a reference to the ContentPlaceholder control in the masterpage and add them to it. Something like:
ContentPlaceHolder myContent = (ContentPlaceHolder)this.Master.FindControl("ContentPlaceHolder1");
myContent.Controls.Add(??);
Notice you are using the ContentPlaceHolderID value, NOT the ID of the asp:Content section.
I will recommend that you put a placeholder control in content and use it to add controls. For example,
<%# Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Basket.aspx.cs" Inherits="Basket" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<asp:Placeholder runat="server" ID="Content1Controls" />
</asp:Content>
..
And
protected void Page_Load(object sender, EventArgs e)
{
Content1Controls.Controls.Add(...
}

locate label on content page

I am trying to locate a label on a content page from within User Control(ascx)
Page p = this.Page;
//this line causes application to unload with no exception
ContentPlaceHolder cp = (ContentPlaceHolder)p.Master.FindControl("Content2");
Label label = (Label)cp.FindControl("SomeLabel");
It just unloads itself with no exception mesage. Why does it happen?
I was able to get this to work so that it finds a Label from within a ContentPlaceHolder where my user control resides:
Site1.Master:
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
Default.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestWeb._Default" MasterPageFile="~/Site1.Master" %>
<%# Register Src="WebUserControl1.ascx" TagName="stuff" TagPrefix="uc" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:Label ID="Label1" Text="Label" runat="server" />
<uc:stuff ID="test" runat="server" />
</asp:Content>
WebUserControl1.ascx.cs:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.Master != null)
{
Control c = Page.Master.FindControl("ContentPlaceHolder1");
if (c != null)
{
Label l = (Label)c.FindControl("Label1");
}
}
}

Resources