views:

863

answers:

9

Hi. I'm very new to ASP.NET, help me please understand MasterPages conception more.

I have Site.master with common header data (css, meta, etc), center form (blank) and footer (copyright info, contact us link, etc).

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Site.master.cs" Inherits="_SiteMaster" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head id="tagHead" runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link rel="stylesheet" href="styles.css" type="text/css" />
</head>
<body>
    <form id="frmMaster" runat="server">
    <div>
        <asp:ContentPlaceHolder ID="holderForm" runat="server"></asp:ContentPlaceHolder>
        <asp:ContentPlaceHolder ID="holderFooter" runat="server">Some footer here</asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

and I want to use second master page for a project into sub directory, which would contains SQL query on Page_Load for logging (it isn't necessary for whole site).

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Project.master.cs" Inherits="_ProjectMaster" MasterPageFile="~/Site.master" %>
<asp:Content ContentPlaceHolderID="holderForm" runat="server">
    <asp:ContentPlaceHolder ID="holderForm" runat="server" EnableViewState="true"></asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ContentPlaceHolderID="holderFooter" runat="server">
    <asp:ContentPlaceHolder ID="holderFooter" runat="server" EnableViewState="true"></asp:ContentPlaceHolder>
</asp:Content>

But I have a problem: footer isn't displayed.

Where is my mistake? Am I right to use second master page as super class for logging?

Project page looks like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" MasterPageFile="~/Project.master" %>
<asp:Content ContentPlaceHolderID="holderForm" runat="server">
    <p>Hello World!</p>
</asp:Content>
<asp:Content ContentPlaceHolderID="holderFooter" runat="Server">
    Some footer content
</asp:Content>
A: 

Hi,

I may be misunderstanding your problem - but from the code you've posted, there isn't anything in the footer.

In your Project page, the <asp:Content> tag for the holderFooter content place holder doesn't have anything in it.

Chris Roberts
Yea, you're right. My mistake - I have removed everything from footer for small code size. If I would put a code in the footer, it will not be shown
abatishchev
A: 

I have next inheritance tree:

Site.master <-- Page1.aspx
<-- Project.master <-- Page2.aspx

And I don't know why Page2 display only content of itself and it's master page - Project. But doesn't display a content of Site (as Page1 does) Why? What have I to write for doing that?

abatishchev
+8  A: 

I've been working with nested master pages and have run in to something similar. From what I see where you have "Some footer here" in the Site.Master is where the problem lies and I've had similar problems with having content with-in a contentplaceholder tag. if you try this instead

<asp:ContentPlaceHolder ID="holderFooter" runat="server"/>Some footer here

Then you should be able to see the footer content.

TWith2Sugars
Thanks a lot! This is what I was searching for.
abatishchev
Not a problem ;)
TWith2Sugars
+2  A: 

You should leave your ContentPlaceHolder empty, for it gets substituted by the content of the Content in your actual Page...

When you move the "Some footer here" text to your Content, you will see your lines of text :)

HTH

Arcturus
+1  A: 

The problem is, when the text elements placed inside Default.aspx are put in their relative Content Placeholders, they are written on the placeholders of your Site.master page and not those of Project.master (which have the same names).

You should resolve the naming conflict, by assigning different ContentPlaceHolderIDs to the the placeholders in Project.master (this means you'll also have to change the references in Default.aspx).

This would be your Project.master file:

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Project.master.cs" Inherits="_ProjectMaster" MasterPageFile="~/Site.master" %>
<asp:Content ContentPlaceHolderID="holderForm" runat="server">
    <!-- whatever... -->
    <asp:ContentPlaceHolder ID="holderFormInternal" runat="server" EnableViewState="true"></asp:ContentPlaceHolder>
    <!-- ... -->
</asp:Content>
<asp:Content ContentPlaceHolderID="holderFooter" runat="server">
    <asp:ContentPlaceHolder ID="holderFooterInternal" runat="server" EnableViewState="true"></asp:ContentPlaceHolder>
</asp:Content>

And thus, your .aspx pages that use the Project master page instead of the global Page.master must be changed to:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" MasterPageFile="~/Project.master" %>
<asp:Content ContentPlaceHolderID="holderFormInternal" runat="server">
    <p>Hello World!</p>
</asp:Content>
<asp:Content ContentPlaceHolderID="holderFooterInternal" runat="Server">
</asp:Content>
Lck
I've used contentplaceholders with the same name for a master page and its nested master page and did not have this problem.
TWith2Sugars
Thanks for your tip, I did it already and got no result. I have to use one-tag <asp:ContentPlaceHolder /> instead of opening and closing tags style.
abatishchev
+2  A: 

This link gives a simple explanation on Master pages, http://waxtadpole.wordpress.com/2009/01/16/master-page-content-not-visible-visual-studio-2008/

The question are you right to use child Master pages in this instance - I would say master pages should be helping you solve issues around building a consistent layout, not for whether or not logging should occur.

Paul Rowland
+4  A: 

I'm not sure I'd use master pages for this. If it's really just going to do logging, I'd implement IHttpModule, register it in web.config, and then check whether or not to log based on the path of the request. I think of master pages as being about content rather than other processing such as logging.

See the IHttpModule walkthrough on MSDN for an example - in your BeginRequest handler, you'd probably check the request path and log appropriately if it matched.

Apologies if I misunderstood what you're trying to do though.

Jon Skeet
My main problem was about using master pages, and thanks a lot for your tip about logging, I will use it.
abatishchev
I was mostly addressing this part: "Am I right to use second master page as super class for logging?" If you go a different route to not use nested master pages, you don't need to worry about the finer details :)
Jon Skeet
+1  A: 

If the only reason is to implement loggin why would you mess around with masterpages? If the logging isent supposed to display any text!?

You either do as Skeet proposed with an IHTTP handler.. Or lazier one would be do have a class that derives from webpage and implement logging in that class and make your pages that need logging dervice from that..

ex:

public class LoggingPage : : System.Web.UI.Page
{
  public override void OnLoad()
{
// Do logging
}
}

partial class OneOfTheWebPages : LoggingPage
{
 public void onLoad()
{
base.onLoad();
}
}
Richard L
Thanks for idea. But I have a label for SQL errors on pages which has logging. But I think I should rewrite this.
abatishchev
+1  A: 

Another good link for understanding the nested master pages in asp.net is this

HotTester