创建更好的主页






3.46/5 (11投票s)
合并“主页”与“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”渲染)

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,即使您可以通过在基类的 RenderChild
或 Render
方法中添加一些代码来获取 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
。然后添加一些通用方法,如 Logging
、Session
等。重写 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”渲染)

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

在一个地方——我想称之为 MasterBasePage
——我们可以控制 Web 应用程序的以下内容:
- UI 布局 [来自 MasterPage]
- 会话处理 [来自 BasePage]
- 项目特定属性 [来自 BasePage]
- 日志记录 [来自 BasePage]
- 等等……
Visual Studio 2005 中的问题
在这里,我们在派生页面中没有使用 MasterPage 的 page 指令属性,因此 Visual Studio 2005 在设计器中会给出一些错误,提示使用内容占位符。目前,我正在研究这个问题。
历史
- 2007 年 11 月 14 日 - 发布原始版本