当在一个ASP.NET Web页面中进行操作时,在默认情况下向当前页进行提交。这种行为在ASP.NET出现之前并没有什么关系,但在ASP.NET中,当我们想向另外一个Web页提交一个Web Form时该如何做呢?在ASP.NET1.0中这个问题变得很难解决,但在ASP.NET 2.0中为开发人员提供了更容易的解决技术:跨网页提交。这种技术允许一个网页在提交数据时提交给另外的一个页面。在跨网页提交中,用于初始化提交代码的页面叫源页面,而客户提交的页面叫目标页面。
为了方便起见,目标页面仍然获得原页面提交的所有数据。换名话说,从技术观点出发,我们可以用同样的方式处理其他ASP.NET页面提交的数据。
这个新特性意味着ASP.NET2.0开发人员目前有三种可供选择的技术来将数据从一个web页面传送到另外一个页面。这三种方法是:响应重定向,服务端传输和新的跨网页提交特性。我们可以已经熟悉前两种技术了,因此,我们只是简要地复习一下它们,然后我们会将主要精力放到学习如何使用跨网页提交特性,以及阐述一下这种方法和响应重定向以及服务传输方式有什么不同。
一、响应重定向方法
响应重定向方法是目前为止将一个网页重定向到另一个网页的最简单的方法的最简单的方法。当Web服务器接到一个重定向请求后,它会将一个响应头送给客户端,这将导致客户端发送一个新的请求到服务器。按句话说,一个重定向请求实际上是两个请求响应:一个是最初的请求响应,另一个是新的重定向请求响应。
在ASP.NET中实现重定向很容易。下面的代码演示了如何使用Response.Redirect方法实现网页重定向:
protected void Redirect_Click(object sender, EventArgs e) Response.Redirect("menu.aspx"); } |
要注意的是重定向请求只是一个GET请求,这就意味着我们不能从源页中通过重定向命令提交数据。但是我们可以在重定向中使用查询字符串来传递数据。如下面代码所示:
protected void Redirect_Click(object sender, EventArgs e) Response.Redirect("menu.aspx?userName=" + UserName.Text)); } |
上面的例子将一个查询字符串作为参数传递给了Response.Redirect方法的目标URL。我们可以通过如下的代码获得源数据。
protected void Page_Load(object sender, EventArgs e) string userName = Request["userName"]; } |
二、服务器传输方法
和依赖于客户端向另一个新页发请求不同,服务器传输是一种服务器重定向技术,这种技术通过简单的改变Web服务器所处理的代码来达到请求一个新页的目的。当被请求页和源页面在同一个服务器时,服务器传输要比Response.Redirect方法更有效,这是由于这种技术可以避免额外的开销,仅仅使用服务器的资源就可以进行重定向。要注意的这种技术有一个副作用,在页面进行重定向时,客户端的URL仍然会保持源页面的URL,这可能会使客户认为他们所获得的数据是源页面产生的。当然,在大多数情况下,这不是问题,但是这将使调试变得更困难。
Server.Transfer方法还可以保存初始页的HttpContext。因此,目标页可以访问源页面的值。我们可以使用FormsCollection属性来从目标页面中获得源页面的值。首先,要确定我们使用了被重载的方法,这个方法有两个参数:目标URL和一个Boolean类型的值,告诉服务器是否保存用于描述源页面值的 Form。如下面的代码所示:
Server.Transfer("Menu.aspx",true); |
然后,我们在目标页面中获得一个叫txtUserName的Textbox控件的值的代码如下:
object obj = Request.Form["txtUserName"]; |
三、Response.Redirect和Server.Transfer的比较
由于Response.Redirect方法要进行两次请求响应操作,因此,我们应该在对性能要求高的网站尽量避免使用这种方法。然而,只从技术上说,使用redirect方式确实可以从一个网页跳到另一个网页。相比之下,Server.Transfer会更有效率,但是跳转的范围仅限于同一个Web服务器的不同网页。从本质上说,我们可以使用Server.Transfer来消除不必要的请求响应操作。如果我们需要重定位到不同服务器的网页,就需要使用Response.Redirect方法。
四、跨页提交概述
在ASP.NET 2.0中,我们可以通过实现IbuttonControl接口提交给不同的WebForm,来实现跨网页的提交。和Response.Redirect类似,跨网页提交是一个基于客户端的传输机制,但也有点象Server.Transfer,目标网页也可以访问源网页的数据。为了使用跨网页提交,我们需要在源网页中的PostBackUrl属性中指定目标URL。
五、实现跨网页提交
这部分将讨论一下如何在 ASP.NET2.0中实现跨网页提交。为了开始我们的学习,假设有两个Web页,一个是源Web页,另一个是目标Web页。在源网页中初始化了使用按钮进行的跨网页提交操作。我们首先必须设置目标网页按钮的PostBackUrl属性,顺便说一句,所有实现了 System.Web.UI.WebControls.IbuttonControl接口的Web控件都有跨网页提交的特性。下面的代码将演示这一过程。
PostBackUrl="~/target.aspx" text = "Post to a target page"/> |
当我们设置PostBackUrl属性时,ASP.NET框架将相应的控件绑定到一个新的叫WebForm_DoPostBackWithOptions的JavaScript函数,产生的Html代码如下:
οnclick="javascript:WebForm_DoPostBackWithOptions( "Target.aspx", false, false))" id="btnSubmit" /> |
对于上面的html代码来说,当用户单击按钮时,浏览器将提交目标URL(Target.aspx),而不是源URL。
六、从目标页面中获得源页面控件的值
ASP.NET2.0提供了一个叫PreviousPage的新的属性,这个属性无论在何时当前页面进行跨网页提交操作时都会指向源页面。要注意的是,当源页面和目标页面在不同的应用程序中时,这个属性包含null(这个null并不是未初始化的意思)。还有要注意的是当目标网页访问 PreviousPage属性时可以获得源页面的数据,ASP.NET运行时装载并执行了源页面。这将引发ProcessChildRequest事件的发生。而且,它还会引发Page_Init事件、Page_Load和任何其他的源页面按钮单击事件。
因此,我们要避免由于不小心进行误操作,所以最好通过IsCrossPostBack属性来确认是否为一个跨网页提交发生,如果这个属性值为true,那么目标网页就是通过一个跨网页提交动作而调用的。如果是通过另外一种方式调用的(如一般的请求、Response.Redirect或是一个Server.Transfer),这个属性的值为false。下面的例子演示了如何使用这个属性。
if ( PreviousPage.IsCrossPagePostBack) //执行代码 } |
这个PreviousPage属性在Server.Transfer和跨网页提交中都可以使用。在ASP.NET2.0中,我们可以在调用Server.Transfer操作后使用PreviousPage属性在目标页面中来获得源页面的数据,代码如下:
{ Server.Transfer("menu.aspx"); } protected void Redirect_Click(object sender, EventArgs e) |
在这个接收面中我们现在可以获得Web页面的数据,代码如下:
protected void Page_Load(object sender, EventArgs e) if (PreviousPage != null) { TextBox txtBox = (TextBox) PreviousPage.FindControl("txtUserName"); if (textBox != null) string userName = textBox.Text; //其他可执行的代码 } } |
要注意的是上面的代码必须将txtUserName控件转换为TextBox类型,以便可以访问其中的值。
七、使用PreviousPageType
PreviousPageType属性提供了在跨网页操作中访问源页面的强类型能力,下面让我们演示一下如何不通过任何类型转换来从源页面中获得控件值。代码如下:
< asp:Textbox ID="txtUserName" Runat="server" /> < asp:Textbox ID="txtPassword" Runat="server" /> < asp:Button ID="Submit" Runat="server" Text="Login" PostBackUrl="Menu.aspx" /> |
要注意的是单击按钮可以重定向到一个叫“Menu.asp”的目标页。这个目标页可以使用如下的代码获得用户名和密码:
八、保存视图状态
对于跨网页提交来说,ASP.NET 2.0 内嵌了一个叫__POSTBACK的隐藏字段,这个字段包含了关于源页面的视图信息 -- 也就是由源页面提供了,包含了一个带有一个非空PostBackUrl属性值的服务端控件。目标页可以使用__POSTBACK中的信息来获得源页面的视图状态信息。代码如下:
if(PreviousPage!=null && PreviousPage.IsCrossPagePostBack && { TextBox txtBox = PreviousPage.FindControl("txtUserName"); Response.Write(txtBox.Text); } |
在上面的代码中核对了用于确保PreviousPage属性不为null的检查代码。顺便提一下,如果目标页和源页面不在同一个应用程序中,这个 PreviousPage属性的值为null。只有在进行跨网页提交操作时,IsCrossPagePostBack属性才为true。
这个跨网页提交的特性,是ASP.NET2.0中最强有力的特性之一,这种技术将允许在一个页面中提交到另外一个页面,并且可以在目标页面地无缝地操作源页面中的数据。
三、如何选择页面重定向方法
在asp.net中有四种页面跳转导航方式,该如何为你的页面选择一个呢?
·如果要让用户来决定何时转换页面以及转到哪一个页面,超级链接最适合。
·如果要用程序来控制转换的目标,但转换的时机由用户决定,使用Web服务器的HyperLink控件,动态设置其NavigateUrl属性。
·如果要把用户连接到另一台服务器上的资源,使用Response.Redirect。
·用Response.Redirect把用户连接到非ASPX的资源,例如HTML页面。
·需要把查询字符串作为url一部分保留传给服务器的时候,因为其他2种方法不能做到2次postback,把数据先带回服务器 ,使用Response.Redirect。
·如果要将执行流程转入同一Web服务器的另一个ASPX页面,应当使用Server.Transfer而不是Response.Redirect,因为Server.Transfer能够避免不必要的网络通信,从而获得更好的性能和浏览效果。
·如果要捕获一个ASPX页面的输出结果,然后将结果插入另一个ASPX页面的特定位置,则使用Server.Execute。
·如果要确保HTML输出合法,请使用Response.Redirect,不要使用Server.Transfer或Server.Execute方法。
顺便提一下,如何使用redirect方法在查询字符串中使用汉字,因为经常的情况是出现乱码,原因是url不支持汉字。这个时候需要转换:
string message =server.urlencode("欢迎来到赛跑专栏");
先转换,在使用查询字符串
response.redirect("webform2.aspx?msg="+message);
关于Server.Execute
这种页面导航方式类似于针对ASPX页面的一次函数调用,被调用的页面能够访问发出调用页面的表单数据和查询字符串集合,所以要把被调用页面Page指令的EnableViewStateMac属性设置成False。
默认情况下,被调用页面的输出追加到当前应答流。但是,Server.Execute方法有一个重载的方法,允许通过一个TextWriter对象(或者它的子对象,例如StringWriter对象)获取被调用页面的输出,而不是直接追加到输出流,这样,在原始页面中可以方便地调整被调用页面输出结果的位置。