用 ASP.NET 页面模板实现更多功能






4.30/5 (27投票s)
2002 年 11 月 25 日
10分钟阅读

242560

1841
页面模板可以提供比设计一致性更多的功能。
引言
当我们听到“ASP.NET 页面模板”时,通常会认为它是一种在网站上保持设计一致性的方式。但理想情况下,您的页面模板应该为您做更多的事情。为什么只停留在设计一致性上呢?您甚至应该尝试从中获得功能一致性。
什么是页面模板?
当有一个 ASP.NET 开发团队构建页面时,理想情况是所有页面都保持设计和功能一致性。但通常情况并非如此。最后,您会得到一组页面——它们的外观和行为都各不相同。这就是页面模板的作用——页面模板只是一个类,它负责渲染所有页面共有的功能,例如页眉、徽标、左/右菜单、页脚、帮助链接等。
页面模板类将继承自 System.Web.UI.Page
。每个页面的代码隐藏类将继承自页面模板类,而不是 System.Web.UI.Page
。
如何创建页面模板?
创建一个继承自 System.Web.UI.Page
的类。
重写 Render
方法 –
protected override void Render(HtmlTextWriter writer)
{
writer.Write(@"<html>
<head></head>
<include html code for header, logo, left menu, tables
(up to the point where your aspx form is to be shown)>
");
// this is responsible for the generation of you aspx
base.Render(writer);
writer.Write(@"
</td>
<close all tables. Include html code for footers, etc>
</body></html>");
}
上述代码是创建页面模板最简单的方法。
现在,确保所有 aspx 页面的代码隐藏都继承自您刚刚创建的类。
此外,请务必
- 从 aspx 源中删除所有
<HTML>, <HEAD>, <BODY>, <TABLE>
起始和结束标签。基本上,删除您已在 Render() 方法中包含的任何内容。 - 从 aspx 源中删除所有绝对定位样式属性,即,原来如下所示的标签代码:
<asp:Label id="Label1" style="Z-INDEX: 101; LEFT: 8px; POSITION: absolute; TOP: 8px" runat="server">Label</asp:Label>
现在应该像这样:
<asp:Label id="Label1" runat="server">Label</asp:Label>
我的页面模板还能做什么?
我们已经了解了如何通过使用页面模板来确保设计一致性。让我们更进一步,尝试用它做更多的事情。
我们必须确保团队中的所有 ASP.NET 开发人员编写的页面在集成时需要最少返工。这意味着所有页面在设计和行为上都必须保持一致。
以下是网站中所有页面共有的行为功能列表 –
- 会话处理 – 通常,您必须明确设置通用的会话变量,如用户 ID、语言等。此外,您必须重复进行会话检查,以查看是否有有效用户登录。
- 国际化 – 所有页面都需要访问资源文件来处理不同语言的文本显示。此外,您必须为每个页面明确设置 Culture 对象。
- 数据库连接 – 所有页面都将与一个类交互,该类通过 ADO.NET 处理数据库连接。或者,您的页面本身将打开一个数据库连接。
- 错误处理 – 所有页面在遇到错误时都将以相同的方式处理 – 记录错误,重定向到错误页面并显示适当的错误消息。
- 使用实用程序类 – 所有页面都将与一组用于邮件、日志记录等的实用程序类交互。
- 帮助功能 – 所有页面在点击帮助按钮时都将以相同的方式处理 – 打开帮助窗口,显示帮助文件。所有帮助文件都将分组在一起。
- 按钮功能 – 所有页面都将有一组通用按钮。有些页面可能显示所有按钮,有些则可能不显示。例如 – 一个网站的所有页面(除了第一页和最后一页)可能都有 3 个按钮(继续、重新开始和退出)。
现在,您可以在页面模板本身中提供所有这些功能。您不再需要担心团队中的 ASP.NET 开发人员在不同页面中提供这些功能不一致的问题。此外,您的开发人员将节省时间,因为他们不必担心这些功能。
我该怎么做?
会话处理功能可以通过以下方式在页面模板中提供 –
- 在页面模板类中重写
OnLoad
方法。 - 在
OnLoad
方法中,执行所有会话检查 - 例如,检查会话中是否提供了用户 ID。 - 如果没有,如果当前页面不是以下三个页面之一,则重定向到错误页面:
- 您网站的第一页
- 负责设置会话变量的页面。
- 错误页面
优点
- 开发人员无需编写重复代码来验证用户会话,以及在超时/无效用户时进行重定向。
国际化功能可以通过以下方式在页面模板中提供 –
- 在
OnLoad
方法中 – - 检查
ResourceManager
是否在 Application 对象中。 - 如果不在,则创建一个新的
ResourceManager
对象指向您的资源文件并将其存储在 Application 对象中。 - 将
ResourceManager
对象设置在一个私有变量中。 - 此外,根据会话中的语言变量设置
CurrentCulture
和CurrentUICulture
对象。 - 在页面模板中提供一个受保护的方法(例如
GetResource
),该方法返回传递给它的键的适当文本(从资源文件中)。此方法使用在OnLoad
中设置的私有ResourceManager
对象。
优点
- 开发人员无需重复检查用户的语言偏好,然后设置 Culture 对象。这由模板的
OnLoad
方法完成。 - 使用单个方法从资源文件获取数据。
- 资源文件是在页面模板类本身中设置的,而不是由单个开发人员设置的。这避免了由于页面和开发人员之间资源文件名称不正确而可能引起的任何问题。
数据库连接和实用程序类可以通过将它们设置为属性的方式在页面模板中提供。然后它们可以被您的代码隐藏类访问。这些属性的初始化可以在 OnLoad
中完成。或者,您可以在页面模板类中提供方法来初始化它们。然后可以从代码隐藏中调用这些方法。
优点
- 确保团队中所有开发人员一致地使用连接字符串、实用程序类、日志记录器、数据访问对象等功能。
- 这些实用程序类的初始化也可以在模板中完成,从而减少不一致的可能性。
- 由于所有开发人员都必须通过模板访问实用程序类,因此可以最大程度地减少集成问题。
- 确保不会因为连接字符串、日志文件名称、电子邮件 ID 等不匹配或不正确而出现任何错误。
错误处理功能可以通过以下方式在页面模板中提供 –
- 在
PageTemplate
类中包含一个ErrorCode
属性。 - 添加一个方法
SetErrorCode(int code)
,该方法设置上述属性并重定向到您的错误页面。当遇到错误/异常时,可以从代码隐藏中调用此方法。 - 您的错误页面将能够通过以下方式检索错误代码:
int errorCode = ((PageTemplate)Context.Handler).ErrorCode;
此错误代码可用于从资源文件中检索适当的错误消息。
优点
- 确保团队中所有开发人员一致地处理错误/异常 – 从而在集成过程中节省时间。
- 确保重定向到错误页面、错误日志记录和错误显示在不同页面和开发人员之间以完全相同的方式发生。
帮助功能可以通过以下方式在页面模板中提供 –
- 在
PageTemplate
类中包含一个HelpURL
属性。此属性在 Render() 方法中使用。 - 此属性在 aspx 的代码隐藏中设置。
优点
- 确保团队中的开发人员一致地处理帮助功能 – 从而在集成过程中节省时间。
- 开发人员无法对帮助文件的路径进行硬编码。路径已在模板中硬编码,因此开发人员只需提供帮助文件的名称。
- 在模板中设置帮助避免了由于一些开发人员使用绝对路径而另一些开发人员使用相对路径访问帮助文件而引起的问题。
按钮功能可以通过以下方式在页面模板中提供 –
- 在
PageTemplate
类中为每个按钮包含boolean
属性。这些属性在 Render() 方法中用于显示/隐藏相应的按钮。 - 此属性在 aspx 的代码隐藏中设置。
优点
- 开发人员无需关心页面上按钮的渲染。布尔属性控制按钮的显示。这在向导式页面中最为有用。
- 在模板中设置按钮及其功能,避免了由于一些开发人员使用绝对路径而另一些开发人员使用相对路径而引起的问题。
您还可以根据您网站的需求向模板添加更多功能。
提供的 ASP.NET 示例应用程序是页面模板实际应用的例子。页面模板类是 PageTemplate.cs。所有代码隐藏类都继承自它。该示例包括一个表单 (FirstPage.aspx),它提交到一个详细信息页面 (SecondPage.aspx)。还提供了一个搜索页面 (searcher.aspx) 和一个错误页面 (Error.aspx)。
查看这些页面中的每一个,并注意几乎不需要任何代码(每个 aspx)即可提供会话检查、i18n 设置、DB 和实用程序类设置、错误处理等。然而,每个页面始终以完全相同的方式运行!提供上述所有功能的代码都在 PageTemplate.cs 中。
如果您使用普通的页面模板,那么每个开发人员都必须在每个页面中包含相同的代码,以提供上面列出的所有功能。我们都知道这可能有多痛苦!
示例用法
这是一个在新项目中使用此模板的快速指南 -
- 创建一个新的 C# ASP.NET Web 应用程序。将其命名为 TestTemplate。
- 将 PageTemplate.cs、Error.aspx 和 Error.aspx.cs 复制到 TestTemplate 目录。打开这些文件中的每一个,并将其中指定的命名空间更改为 TestTemplate。保存更改,关闭文件,然后将 Error.aspx 和 PageTemplate.cs 添加到项目中。重新生成项目。
- 将资源文件 (MyResources.fr.resx 和 MyResources.resx) 复制到 TestTemplate 目录,然后将它们添加到项目中。此外,请确保在 PageTemplate.cs 的
OnLoad()
方法中正确指定了资源文件,即OnLoad()
中的以下行:
Application["resources"] = new ResourceManager("MyTemplate.MyResources",Assembly.GetExecutingAssembly());
现在变成Application["resources"] = new ResourceManager("TestTemplate.MyResources",Assembly.GetExecutingAssembly());
重新生成项目。 - 添加一个新的 Web 表单,并将其命名为 FirstPage.aspx。此页面将是您网站中第一个调用的 aspx。因此,此页面会将用户 ID 和语言设置到会话中。
在 FirstPage.aspx 的 HTML 源中,删除除表单标签之外的所有 HTML 标签。也就是说,您的 HTML 源现在看起来像这样:<%@ Page language="c#" Codebehind="FirstPage.aspx.cs" AutoEventWireup="false" Inherits="TestTemplate.FirstPage" %> <form id="FirstPage" method="post" runat="server"> </form>
在设计器模式下向表单添加控件。不要添加按钮来提交表单。
将 FirstPage.aspx 设置为项目的启动页。
将代码隐藏的父类从System.Web.UI.Page
更改为 PageTemplate。
在Page_Load
方法中,执行以下操作:if ( IsPostBack ) { // do any action on postback } else { // get Language code & user ID from previous HTML page or elsewhere string languageCode = "en"; string userID = "superman"; // this call sets the language & user ID in the session setLanguageAndUser(languageCode, userID); } // This sets the help file's url for this page HelpURL = "first_page_help.html";
- 运行项目。您将看到 FirstPage.aspx 带有许多额外内容 -
- 左侧菜单
- 标题
- 页脚
- 搜索框
- 日期信息
- 用户登录信息
- 继续、重新开始和退出超链接
- 帮助超链接
- 现在,将语言代码更改为“fr”,然后再次查看。您将看到大多数标签的文本已更改。
- “继续”超链接调用一个 JavaScript 函数 -
continueForm()
。此方法应在每个 aspx 的 HTML 源中重写以提交表单。即 - 您可以在 aspx 页面的 HTML 源中包含以下内容:<script> function continueForm() { alert("submitting......"); document.FirstPage.submit(); } </script>
现在,看看当您点击“继续”时会发生什么。请注意,您可以提供其他方式来提交表单。我碰巧使用了“继续”超链接。 - 在
Page_Load
中处理一个异常,看看会发生什么。即在回发部分 -if ( IsPostBack ) { try { throw new Exception(); } catch (Exception ex) { SetErrorCode(1); } }
您会看到在提交后,页面会自动重定向到错误页面。此外,还显示了一条从资源文件中获取的消息。
此外,当会话超时时,会自动重定向到错误页面(带错误代码)。 - 添加更多页面甚至更容易 -
- 添加一个新的 Web 表单。
- 删除除表单标签外的所有 HTML 标签。添加您的控件。
- 将代码隐藏的父级更改为 PageTemplate。
- 如有必要,重写
continueForm()
。 - 仅提供与该页面相关的功能。不需要会话检查、i18n 设置、DB 和实用程序类设置、错误处理等代码。
- 除了第一个 aspx 页面(即这里的 FirstPage.aspx)之外,您无需在任何页面中调用
setLanguageAndUser()
。
- 要更改模板渲染的 HTML,请修改 PageTemplate 的
Render
方法中的 HTML 源。