一、单窗体模型
ASP.NET页面只支持一个服务器端<form>标签,这称为ASP.NET页面的单窗体模型。ASP.NET的单窗体还具有如下特点:
- 服务器端<form>标签会被映射到HtmlForm类的实例。
- 所有服务器端控件必须全部置于该窗体中。
二、页面间数据传递
1、HTML中<form>标签的Action属性
在HTML中,<form>标签的Action属性用于指示被投递页面的URL地址。例如:
<form id=”form1” method=”post” action=”target.aspx”>
…
</form>
这种方法的问题在于状态信息不会被自动存储。
2、跨页投递
在ASP.NET中HtmlForm类并没有暴露任何相当于HTML<form>标签的Action属性,跨页投递的方法有所不同。
1)跨页投递方法
在ASP.NET中,跨页投递是通过设置回发控件的PostBackUrl属性来实现的。例如:
<form id=”Form1”, runat=”server”>
<asp:textbox runat=”server” id=”Data” />
<asp:button runat=”server” id=”buttnPost” Text=”Click” PostBackUrl=”target.aspx” />
</form>
当PostBackUrl属性被设置后,ASP.NET运行库会将按钮控件相应的HTML元素(onclick属性)绑定到一个JavaScript函数上,JavaScript函数用来实现跨页投递。
2)取得投递页面的视图状态
当页面包含用于执行跨页回发的控件时,会有一个新的隐含字段被创建——_PREVIOUSPAGE,该字段包含处理请求所需的视图状态信息,用以恢复投递页面的原视图状态。
我们可以使用PreviousPage属性来引用主动投递页面及其中的控件。例如:
protected void Page_Load(object sender, EventArgs e)
{
// retrieves posted data
Textbox txt = (TextBox)PreviousPage.FindControl(“TextBox1”);
…
}
3)跨页投递的检测
对于目标页面,它既可能是自身投递给自身,也可能是跨页投递过来的,检测当前页面是否是跨页投递的目标页面的最有效办法就是判断PreviousPage属性。例如:
if (PreviousPage != null)
{
Response.Write(“It’s cross page post.”);
Response.End();
return;
}
3、服务器传输
服务器传输是另一种在页面间传递数据的方法。例如:
Protected void Button1_Click(object sender, EventArgs e)
{
Server.Transfer(“target.aspx”);
}
在该页面中,所有在Transfer方法之后的代码都不会被执行。
服务器传输也是一种有效的页面间数据传递方法,因为:
- 该方法不会引发到客户端的往返,Response.Redirect则相反。
- 它复用了处理调用者请求的HttpApplication对象,从而降低了对ASP.NET HTTP运行时的影响。
同跨页传递一样,我们可以利用PreviousPage属性取得主调页面对象实例。
三、母版页
1、母版页的编写
母版页与标准的ASP.NET页面很相似,但其顶部指令是@Master,并包含若干ContentPlaceHolder服务器控件。ContentPlaceHolder控件用于在母版页定义内容页中的可自定义区域。
母版页文件会被编译为派生自MasterPage的类,MasterPage类继承于UserControl,归根到底,母版页会被当做特殊的ASP.NET用户控件。
2、内容页的编写
内容页是一种包含<asp:Content>的特殊页面,它不允许在<asp:Content>标签以外包含任何服务器控件。Content控件用于链接母版页相应的ContentPlaceHolder控件。
通过@Page指令的MasterPageFile属性,可以将内容页被绑定到母版页,同时@Page指令的Title属性可以设置内容页的标题。
3、内容页访问母版页
内容页可以通过Page类的Master属性来引用母版页对象,但是Master属性被定义为MasterPage类型,所以无法直接访问母版页的public成员,有两种解决办法:
1)强制类型转换
定义母版页的Classname,例如:
<%@ Master Inherits=”SimpleWithProp” … Classname=”MasterWithProp” %>
内容页通过类型转换访问母版页的public成员,例如:
((ASP.MasterWithProp)Master).TitleBoxText = “ASP.NET 3.5 programming”;
ASP命名空间是系统的命名控件,包含所有系统动态定义的类型。
2)@MasterType指令
在内容页中添加@MasterType指令会提示编译器Master属性的真正类型,这样Master属性会被声明为正确的类型,避免上面的类型转换。
四、页面的个性化
ASP.NET中有两种互补的个性化形式:用户配置文件(user profile)和主题(theme)。
1、user profile
1)user profile的创建
User profile是一个包含若干页面个性化属性的类,这个类是由ASP.NET运行库动态生成的,用户可以在web.config文件中的<profile>区段定义页面个性化属性,由ASP.NET运行库生成user profile类。例如:
<profile>
<properties>
<add name=”BackColor” type=”string” />
<add name=”ForeColor” type=”string” />
</properties>
</profile>
则ASPNET运行库会自动生成user profile类。
public class ProfileCommon : ProfileBase
{
public virtual string BackColor
{
get { (string)GetPropertyValue(“BackColor”); }
set { SetPropertyValue(“BackColor”, value); }
}
public virtual string ForeColor
{
get { (string)GetPropertyValue(“ForeColor”); }
set { SetPropertyValue(“ForeColor”, Value); }
}
public virtual ProfileCommon GetProfile(string userName)
{
object o = ProfileBase.Create(username);
return (ProfileCommon)o;
}
}
在web.config定义的属性可以使用CLR中的任何类型,甚至是自定义类型。
2)user profile的访问
user profile是与用户账号关联的(从GetProfile方法也可以看出来),每一个账户拥有一个user profile类的实例,用于个性化该用户的页面。
在请求进入处理周期之前,个性化数据(当前用户的user profile实例)会被添加到HTTP的上下文中,并在页面建立时赋值给Page类的Profile属性,利用该属性可以为当前用户生成个性化页面,例如:
theBody.Attributes[“bgcolor”] = Profile.BackColor;
3)user profile的持久性存储
在每一次页面请求结束时,Profile属性的内容会被序列化到持久性存储介质中,以便在页面下一次请求时获取。
为持久性存储user profile我们既可以使用ASP.NET内建的数据库提供程序,也可以使用自定义的提供程序。
2、主题
1)主题的结构
主题由一个.css文件、一个.skin文件和一个images子文件夹构成,并位于应用程序根目录App_Themes文件夹下。其中CSS文件包含应用于HTML文档元素的样式定义;skin文件预定义了ASP.NET服务器控件的可视属性,而且支持模板;images文件夹放置当前主题需要的图像文件。
2)主题的形式
主题有两种形式:自定义主题和样式表主题。应用自定义主题时会重写.aspx源文件中控件的属性定义,而应用样式表主题时.aspx源文件的属性会重写样式表主题中定义的属性值。
3)主题的应用
(1)在web.config中配置主题
theme属性用于设置自定义主题,而styleSheetTheme属性用于设置样式表主题,例如:
<system.web>
<pages theme=”Core35-Basic” />
</system.web>
(2)在页面中配置主题
@Page指令的Theme属性用于设置自定义主题,而StyleSheetTheme属性用于设置样式表主题,例如:
<%@ page Language=”C#” Theme=”Core35-Basic” %>
五、页面错误处理
1、代码方式处理页面错误
Page类提供了Error事件,定义其Error事件处理程序能够在页面级处理特定页面中的错误。
HttpApplication类也有Error事件,同样定义其Error事件处理程序(global.asax文件中定义)能够在应用程序级处理页面中的错误。
Page类以及HttpApplication类的Error事件只能捕获内部错误(HTTP500错误),对于非HTTP500错误(如HTTP404:找不到资源)则需要进一步借助配置方式来处理。
2、配置方式处理页面错误
通过应用程序web.config文件中的<customErrors>区段,开发者可以对页面错误处理进行定制。
<configuration>
<system.web>
…
<customErrors mode=”RemoteOnly” defaultRedirect=”//Error.aspx”>
<error statusCode=”404” redirect=”/ErrorPage/Error404.aspx” />
<error statusCode=”500” redirect=”/ErrorPage/Error500.aspx” />
</customErrors>
</system.web>
</configuration>
对于mode属性,如果被设置为(Remoteonly),则远程用户收到的是一般性错误提示页面,而本地用户收到的带有调用栈等详细信息的错误页面;如果被设置为Off,则本地和远程用户都会显示包含详细信息的错误页面;如果被设置为On,对于本地用户或远程用户都只是收到一般性错误页面。
六、页面跟踪
跟踪使开发者能够编写调试语句,用于将诊断信息追加到页面的输出中。当应用程序部署到服务器上,通过属性对可以对跟踪功能进行开关控制。
1、页面跟踪的启用
web.config文件中的<trace>区段可以对页面跟踪进行配置:
<configuration>
<system.web>
<trace enabled=”true” pageOutput=”true” />
</system.web>
</configuration>
enabled属性用于指示是否开启应用程序的跟踪,pageOut属性用于提示是否将输出显示在页面中,如果pageOut被设置为false(默认设置),跟踪输出会被自动发送到ASP.NET的跟踪工具(trace.axd)中。
@Page指令的trace属性可以对单个页面的跟踪进行控制,trace属性默认为false,如果设置为true,跟踪消息就会被显示在页面的底部。
2、跟踪消息的编写
Page类的Trace属性用于编写跟踪消息,它是TraceContext类的实例。该类有两个方法用于消息的发送,Write和Warn,两者功能几乎相同,唯一的差别在于Warn输出的消息为红色。
Trace.Write(“Loading page has completed.”);