65.9K
CodeProject 正在变化。 阅读更多。
Home

创建更好的主页

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.46/5 (11投票s)

2007 年 11 月 13 日

CPOL

4分钟阅读

viewsIcon

66818

downloadIcon

775

合并“主页”与“BasePage”

引言

在本文中,我将解释如何将 BasePage 类与 MasterPage 合并,以便您可以控制 UI 和页面功能。

母版页 (MasterPage)

MasterPage 是 ASP.NET 2.0 中的一项新技术,它在通用位置维护整个 Web 应用程序的设计非常有用。使用它,我们可以在短时间内改变应用程序的整体外观和感觉。通常,我们将布局设计保留在 MasterPage 中,所有其他页面将从它继承 UI。

点击这里 了解更多关于 MasterPages 的信息。

这是继承吗?

即使我们从 MasterPage 继承 UI,这也不是一个继承概念。MasterPage 只是提供了一个内容占位符,使派生页面能够提供特定于页面的 UI。

创建一个简单的示例

步骤 1

创建一个带有页眉内容、页脚内容和占位符内容的 MasterPage,如下所示。

MasterPage.Master
<%@ 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>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <h3>Header Contents</h3><hr />
        <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
        </asp:contentplaceholder>
     <hr /><h3>Footer Contents</h3>
    </div>
    </form>
</body>
</html>

第二步

创建一个 WebPage 并使用 page 指令引用 MasterPage,如下所示。

Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" 
    MasterPageFile="~/MasterPage.master"  
    CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content runat="server" ContentPlaceHolderID="ContentPlaceHolder1" 
    ID="PageContent">
<b>Content</b>
</asp:Content>

步骤 3

运行示例。您可以看到带有页眉、页脚和特定页面内容的以下输出。这就是我们将通用 UI 内容(页眉、页脚)放置在通用位置的方式。

输出:Default.aspx (由“MasterPage”渲染)
Screenshot - MasterPageOutPut.jpg

MasterPage 的缺点

MasterPage 仅用于 UI 扩展。您无法通过它获得实际的继承优势。例如,使用继承,您可以在基类中拥有通用方法和属性,所有派生 Web 窗体都可以使用它们,即您可以在基类中进行日志记录、异常处理、会话处理,所有 Web 窗体都可以使用这些。

BasePage

什么是 BasePage?

BasePage 是 ASP.NET 2.0 之前许多开发人员遵循的一个概念。它也被称为“PageBase”、“WebPageBase”等等。BasePage 的概念非常简单:创建一个继承自 System.Web.UI.Page 的类,并使用该类作为所有 Web 窗体的基类。不幸的是,您无法在派生类中获得基类的所有 UI。这是因为在 ASP.NET 中,UI 是使用 Context 方法构建的。继承无助于渲染基类 UI,即使您可以通过在基类的 RenderChildRender 方法中添加一些代码来获取 BasePage UI。

创建一个简单的示例

步骤 1

创建两个用户控件(*.ascx)用于页眉和页脚,如下所示。

HeaderControl.ascx
<%@ Control Language="C#" AutoEventWireup="true" 
    CodeFile="HeaderControl.ascx.cs" Inherits="HeaderControl" %>
<h3>Header Content</h3><hr />
FooterControl.ascx
<%@ Control Language="C#" AutoEventWireup="true" 
    CodeFile="FooterControl.ascx.cs" Inherits="FooterControl" %>
<hr /><h3>Footer Content</h3>

第二步

只需创建一个类并继承自 System.Web.UI.Page。然后添加一些通用方法,如 LoggingSession 等。重写 Render 方法并添加如下代码。

BasePage.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
//Properties: Logger,CurrentSession is just created for the example purpose


/// <summary>

/// Inherit all the web pages from this class, 

/// this will add Generic UI, and Generic functions to the web page

/// </summary>

public class BasePage:System.Web.UI.Page
{
    public BasePage()
    {
        //

        // TODO: Add constructor logic here

        //


        _Logger = new Logger();
    }
    protected override void Render(HtmlTextWriter writer)
    {
        Control header = this.LoadControl("HeaderControl.ascx");
        Control footer = this.LoadControl("FooterControl.ascx");
        
        //Adding at the first the position (Header)

        this.Form.Controls.AddAt(0, header);

        //Adding at the Last position(Footer)

        this.Form.Controls.AddAt(this.Form.Controls.Count, footer);
        

        base.Render(writer);
    }

    private Logger _Logger;

    //note that Derived class cannt create instance of it

    //this is also a kind of controling

    public Logger Logger
    {
        get { return _Logger; }
        
    }

    private SessionData _CurrentSession;

    public SessionData CurrentSession
    {
        get { return _CurrentSession; }
        set { _CurrentSession = value; }
    }

}
Logger 类
/// <summary>

/// This class is responsible for logging

/// Please note that you can also use Microsoft 

/// Enterprise Library Logging Block

/// </summary>

public class Logger
{
    public void LogWarning(object Message)
    {
        //write some logic here

    }
    public void LogError(object Message)
    {
        //write some logic here

    }
    public void LogTrace(object Message)
    {
        //write some logic here

    }
}
会话处理类
public class SessionData
{
    public int UserId
    {
        get 
        { 
            return int.Parse(
                HttpContext.Current.Session["UserId"].ToString());
        }
        set { HttpContext.Current.Session["UserId"] = value; }
    }

    public List<int> ItemIds
    {
        get { return (List<int>)HttpContext.Current.Session["Items"]; }
        set { HttpContext.Current.Session["Items"] = value; }
    }
    
}

注意:上面的会话处理和日志类仅用于解释目的。您还可以根据您的项目添加任何通用元素。

步骤 3

创建一个 Web 窗体并将基类名称从 System.Web.UI.Page 更改为 BasePage

Default2.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Default2 : BasePage
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

结果

现在,我们可以像使用 MasterPage 一样从基类渲染 UI。我们还使用基类提供的方法和属性。所以,我们确实可以从一个地方控制应用程序的 UI 和功能。

输出:Default2.aspx (由“BasePage”渲染)
Screenshot - BasePageOutput.jpg

BasePage 的缺点

这并不是一个经过验证的技术,但即使如此,我已经在许多客户所在地实施过,而且它确实运行良好,即使对于大量请求也是如此。此外,我们只在 <form> 标签内添加控件,因此更新 <head> 标签中的元素(如样式表引用和页面标题)有点困难。

合并 BasePage 和 MasterPage

合并这两种技术,BasePage 和 MasterPage,非常简单。只需将以下代码添加到 BasePage 构造函数中,并删除我们在 Render 方法中添加的代码,这样 BasePage 现在看起来如下。

更改 BasePage.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
//Properties: Logger,CurrentSession is just created for the example purpose


/// <sumary>

/// Inherit all the web pages from this, 

/// this will add Generic UI for the Application

/// </summary>

public class BasePage:System.Web.UI.Page
{
    public BasePage()
    {
        //

        // TODO: Add constructor logic here

        //


        _Logger = new Logger();
        this.MasterPageFile = "MasterPage.Master";
    }
  
    private Logger _Logger;

    //note that Derived class cannt create instance of it

    //this is also a kind of controling

    public Logger Logger
    {
        get { return _Logger; }
        
    }

    private SessionData _CurrentSession;

    public SessionData CurrentSession
    {
        get { return _CurrentSession; }
        set { _CurrentSession = value; }
    }

}

尝试从派生 Web 页面访问 BasePage 提供的通用方法。

继承自 BasePage 的 Default2.aspx.cs 文件的 IntelliSense
Screenshot - VS2005IntelScreen.jpg

在一个地方——我想称之为 MasterBasePage——我们可以控制 Web 应用程序的以下内容:

  • UI 布局 [来自 MasterPage]
  • 会话处理 [来自 BasePage]
  • 项目特定属性 [来自 BasePage]
  • 日志记录 [来自 BasePage]
  • 等等……

Visual Studio 2005 中的问题

在这里,我们在派生页面中没有使用 MasterPage 的 page 指令属性,因此 Visual Studio 2005 在设计器中会给出一些错误,提示使用内容占位符。目前,我正在研究这个问题。

历史

  • 2007 年 11 月 14 日 - 发布原始版本
© . All rights reserved.