ASP.NET 2.0中实现跨页面提交

转载 2007年09月19日 16:21:00
 
ASP.NET 2.0中实现跨页面提交
 
 
 在ASP.NET 1.X 版本中,页面都是提交到自己本身,并不能方便的指定需要提交的目的页面。例如FirstPage.aspx中的button只能提交到 FirstPage.aspx,而不能提交到SecondPage.aspx。很多时候,ASP.NET 1.X这样工作方式使我们的开发方式受到不少限制。熟悉ASP/JSP/PHP的朋友大概很不习惯,因为以前经常使用的提交方式突然无法使用,虽然也有解决这个问题的方法(演示Webcast),可是过程太烦琐,不甚方便。令我们高兴的是,ASP.NET 2.0中有了跨页面提交的简单方法。

  简单的例子

  首先看看下面的代码,FirstPage.aspx中的Button通过指定PostBackUrl属性可以提交到指定的页面:

  FirstPage.aspx

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
public String UserName {
 get {
  return this.txtName.Text;
 }
}
protected void Button1_Click(object sender, EventArgs e)
{
 Label1.Text = "Postback from self. Your Name is: " + txtName.Text;
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
 <meta content="text/JScript" http-equiv="content-script-type" />
 <title>First Page</title>
</head>
<body>
 <form id="form1" runat="server">
 <div>
  <h3>The Frist Page</h3>
  Your Name:
  <asp:TextBox ID="txtName" runat="server" />
  <asp:Label ID="Label1" runat="server" EnableViewState="False" /><br />
  <br />
  <asp:Button ID="Button1" runat="server" Text="Postback to Same Page" OnClick="Button1_Click" /><br />
  <br />
  <asp:Button ID="Button2" runat="server" Text="Postback to Second Page" PostBackUrl="~/SecondPage.aspx" /><br />
 </div>
</form>
</body>
</html>

  SecondPage.aspx

<%@ Page Language="C#" %>
<%@ PreviousPageType VirtualPath="~/FirstPage.aspx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
 this.Label1.Text = "Your Name is : " + PreviousPage.UserName;
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Second Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>This is the Second Page</h1>
<p><asp:Label ID="Label1" runat="server"></asp:Label> </p>
</div>
</form>
</body>
</html>

  打开FirstPage.aspx,输入内容并按下"Postback to Second Page"按钮提交,页面就会提交到SecondPage.aspx,输入的内容也会显示在SecondPage.aspx上。注意 FirstPage.aspx中Button2新增的PostBackUrl属性,还有SecondPage.aspx中的 @PreviousPageType指令。这些新增的内容,正是ASP.NET 2.0 中的跨页提交的方案的组成部分。

  大家可能会发现,在使用ASP.NET 2.0 的跨页面提交功能的时候,目标页面都是在源页面的窗口中打开的。但有时候我们需要在新的窗口中打开目标页面,通过修改源页面中<form>的属性可以实现这一点。如下面的代码所示:

<form id="MainForm" Target="_blank" runat="server">

  读取源页面的信息

  ASP.NET 2.0中,Button控件有个新增的属性PostBackUrl,用来设置需要提交的目标页面。因为只要指定Button控件的PostBackUrl 属性就可以提交到其它页面,我们可以在页面中使用多个控件配置其PostBackUrl的属性,提交到不同的页面。当然也可配置多个页面提交到同一个页面。

  在跨页面提交之后,通常我们需要从源页面中读取控件的信息(即由浏览器发送的信息),以及源页面的公共属性。

  读取控件的值

  ASP.NET 2.0的Page类新增了一个PreviousPage属性。顾名思义,目标页面中的这个属性包含对源页面的引用。这样就可以在目标页面中通过 PreviousPage属性访问源页面的信息,我们一般使用FindControl方法来查找源页面上的控件并读取这些控件的值。下面的代码说明了该方法的使用:

if (Page.PreviousPage != null)
{
 TextBox txtName = (TextBox)Page.PreviousPage.FindControl("txtName");
 if (txtName != null)
 {
  Label1.Text = txtName.Text;
 }
}

  当我们想查找源页面中控件属于另一个控件或者是模板之中,就不能直接使用FindControl方法来读取它,而是应该先获取对该容器的引用,然后才能在该容器中查找要获取的控件。下面的例子中,FirstPage.aspx页面中包含一个Panel控件,其ID为MainPanel,它还包含ID为 UserName的TextBox控件。具体代码如下:

Panel MainPanel = (Panel)PreviousPage.FindControl("MainPanel");
if (MainPanel != null)
{
 TextBox UserName = (TextBox)MainPanel.FindControl("UserName");
 if (UserName != null)
 {
  Label1.Text = UserName.Text;
 }
}
else
{
 Label1.Text = "Cannot find UserName control.";
}

  读取源页面的公共属性

  一旦在目标页面中获取了PreviousPage的引用,就能访问源页面中公共控件的属性,同样也可访问源页面中的公共属性。当然,我们需要预先在源页面中公开需要被访问的属性方可在目标页面中访问。

  若要获取源页面的公共成员,必须先获取对源页面的强类型引用。就像第一个例子中,我们可以使用@PreviousPageType指令来指定源页面,它有两个属性分别为:VirtualPath和TypeName。使用VirtualPath属性指定来源页的虚拟路径(包含文件名),也可以使用 TypeName指定源页面的属性。注意只能指定其中的一个,两者都指定就会失效。如第一个例子中所示:

<%@ PreviousPageType VirtualPath="~/FirstPage.aspx" %>

  如果使用了@PreviousPageType指令,目标页面中的PreviousPage 属性被强类型化为源页面的类。因此,可以直接引用源页面的公共成员。要获取对源页面的强类型引用的另一种方法是在目标页面中包含一个@Reference 指令,就像引用要在页面中使用的其它任何类型一样。在这种情况下,你可以在目标页面中获取目标页面的PreviousPage属性并将其强制转换为源页面的类型,如下面的代码所示:

SourcePage_aspx sourcePage;
sourcePage = (SourcePage_aspx) PreviousPage;
Label1.Text = sourcePage.UserName;

  读取源页面中的Form信息

  如果源页面和目标页面属于同一个 ASP.NET 应用程序,则目标页中的PreviousPage属性包含对源页面的引用。在没有使用@PreviousPageType指令的情况下,目标页面中PreviousPage 属性类型化为Page。

  注意,如果该页不是跨页发送的目标页面或者目标页面位于不同的应用程序中,则不会初始化PreviousPage属性。

  如果源页面和目标页面属于不同的应用程序,甚至是不同的网站,那就无法直接获取源页面上控件的值,但可以从Request.Form中读取发送的数据。还有一个需要注意的问题,因为源页面的视图状态经过Hash处理,所以不能从源页面中读取视图状态。如果要在源页面中存储值并让这些值可供其他应用程序中的目标页使用,可以将这些值作为字符串存储在源页面的隐藏字段中,并在目标页面中通过 Request.Form 来访问它们。

 

  判断是否为跨页面提交

  跨页面提交的时候,源页面控件的内容被提交到目标页面,然后浏览器执行POST操作(注意,不是GET)。在ASP.NET 1.x中由于页面都是自己提交给自己,可以通过Page的IsPostBack属性来判断是否为页面提交。但是在跨页面提交的时候,目标页面的 IsPostBack属性为false。如果要判断是否为跨页面提交,可以对目标页面的PreviousPage属性返回的引用页面的 IsCrossPagePostBack属性进行判断,如下面的代码所示:

if(PreviousPage != null)
{
 if(PreviousPage.IsCrossPagePostBack == true)
 {
  Label1.Text = "跨页面提交";
 }
}
else
{
 Label1.Text = "非跨页面提交";
}

  注意,如果当前页面不是跨页面提交的目标页面,则其PreviousPage属性为空。

  跨页面提交 VS Server.Transfer

  ASP.NET 2.0中,无论是跨页面提交还是使用Server.Transfer操作,都可以使用Previousoage属性来获取对源页面的引用。如果要区分它们,可以使用上面介绍的方法。

  下面是跨页面提交与Server.Transfer之间的一些区别:

属 性
跨页面提交
Server.Transfer
IsPostBack false false
PreviousPage 源页面的引用 源页面的引用
PreviousPage.IsCrossPagePostBack true false
IsCrossPagePostBack false false
IsCallBack false false

  跨页面提交是客户端浏览器的行为,而Server.Transfer则是服务器端的行为。在后面的小节中,我们会分析跨页面提交时客户端浏览器是如何实现提交的。

  对跨页面提交的简单分析

  在上面的例子中,我们都提到设置Button的PostBackUrl属性来实现跨页面提交。其实只要实现IButtonControl接口的控件均可以实现这一点。Button, ImageButton, 和 LinkButton都实现了IButtonControl接口。通过实现IButtonControl,自定义控件也可以有表单中的按钮所具有的跨页面提交的功能。IButtonControl接口聚合了ASP.NET 1.x支持的多数按钮控件(包括一些html按钮控件)的一些属性。

  当设置了Button控件的PostBackUrl属性之后,ASP.NET运行时将为按钮控件的所对应的的html元素绑定一段新的 JavaScript代码。使用新的 WebForm_DoPostBackWithOptions函数取代常规以前所使用的__doPostback函数。具体的HTML代码示例如下:

<input type="submit" name="Button2" value="Postback to Second Page" onclick=WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("Button2", "", false, "", "SecondPage.aspx", false, false))" id="Button2" />

  上述代码中的WebForm_DoPostBackWithOptions函数与WebForm_PostBackOptions函数的javascript代码如下:

function WebForm_PostBackOptions(eventTarget, eventArgument, validation, validationGroup, actionUrl, trackFocus, clientSubmit) {
this.eventTarget = eventTarget;
this.eventArgument = eventArgument;
this.validation = validation;
this.validationGroup = validationGroup;
this.actionUrl = actionUrl;
this.trackFocus = trackFocus;
this.clientSubmit = clientSubmit;
}

function WebForm_DoPostBackWithOptions(options) {
var validationResult = true;
if (options.validation) {
if (typeof(Page_ClientValidate) == 'function') {
validationResult = Page_ClientValidate(options.validationGroup);
}
}
if (validationResult) {
if ((typeof(options.actionUrl) != "undefined") && (options.actionUrl != null) && (options.actionUrl.length > 0)) {
theForm.action = options.actionUrl;
}
if (options.trackFocus) {
var lastFocus = theForm.elements["__LASTFOCUS"];
if ((typeof(lastFocus) != "undefined") && (lastFocus != null)) {
if (typeof(do***ent.activeElement) == "undefined") {
lastFocus.value = options.eventTarget;
}
else {
var active = do***ent.activeElement;
if ((typeof(active) != "undefined") && (active != null)) {
if ((typeof(active.id) != "undefined") && (active.id != null) && (active.id.length > 0)) {
lastFocus.value = active.id;
}
else if (typeof(active.name) != "undefined") {
lastFocus.value = active.name;
}
}
}
}
}
}
if (options.clientSubmit) {
__doPostBack(options.eventTarget, options.eventArgument);
}
}

  用户点击按钮时,当前表单将内容提交给PostPageUrl属性所指定的目标页面。当页面中含有可以实现跨页面提交功能的控件时,页面会创建一个 name为__PREVIOUSPAGE的隐藏字段,此字段包含了源页面的信息。目标页面则使用此信息来创建一个完整状态的引用来调用源页面对象。上述隐藏字段的相关HTML代码示例如下:

<input type="hidden" name="__PREVIOUSPAGE" id="__PREVIOUSPAGE" value="ND3_1GqjDSUeAC3yLYVz-eQrkTzZLYFHliIFf7mMQVBdmwZmFi8HG4mzX5pfZY0n0" />

(二)postbackurl传递数据

方法一       
if (Page.PreviousPage != null)
        {
            TextBox txtName = (TextBox)Page.PreviousPage.FindControl("TextBox_code");
            if (txtName != null)
            {
                Label1.Text = txtName.Text;
            }
        }
方法二
第一个页面在cs中
    public TextBox Ntextbox
    {
        get { return TextBox_code; }
    }

第二个页面   
Label1.Text = PreviousPage.Ntextbox.Text;
 
Server.Transfer 是一个基于服务器的方法,而PostBackUrl是基于客户端的。从这个意义上来讲,跨页面传送比Server.Transfer更加的便捷,有利于提高服务器的性能,减少了处理步骤。除开这一点,两者还是非常相似的,不过在ASP.NET 2.0中,跨页面传送显然是更好的选择。
如果要在后续页面中判断PerviousPage所引用的页面是通过跨页面提交而来的还是通过Server.Transfer方法传送而来的,可以通过IsCrossPagePostBack属性来进行判断
if(PreviousPage != null){
    if(PreviousPage.IsCrossPagePostBack == true)    {
    Response.Write("Cross-page post.");
    }
}
else {
    Response.Write("Not a cross-page post.");
}

 


  总 结

  ASP.NET 2.0 新增的跨页面提交功能,让我们的开发过程有了更加灵活的选择。在使用跨页面提交的时候,我们要根据实际的情况选择合适的方式来读取源页面中的信息。如果源页面与目标页面处于同一个应用程序之内,我们可以选择使用@PreviousPageType指令来指定源页面,这样就可以使用强类型引用的好处。

  由于ASP.NET中的每个页面类所包含的子控件对应的是protected成员,所以您不能直接通过PreviousPage引用来访问源页面中的控件,而先需要将源页面中需要被访问的属性公开出来。同时,建议您只将需要的信息作为公共属性公开,以减少可能被潜在的恶意用户使用的信息。

 

ASP.NET 2.0 中实现跨页面提交

  • 2010年10月18日 21:58
  • 10KB
  • 下载

ASP.NET 2.0中的跨页面提交

简介         在ASP.NET 1.X 版本中,页面都是提交到自己本身,并不能方便的指定需要提交的目的页面。例如FirstPage.aspx中的button只能提交到FirstPage.as...

ASP.NET 2.0 中实现跨页提交

  • 2008年10月20日 15:42
  • 69KB
  • 下载

ASP.NET 2.0无刷新页面新境界(转载)

     “无刷新页面”,只是一种不确切的效果描述(其实还有其他各种方法来实现这个效果),更确切的说法是:在页面上用JavaScript调用服务器端的一个方法,然后处理返回的数据。实现它最标准的方法当...

asp.net 2.0 缓存(页面输出缓存)

页面输出缓存作为最简单的缓存形式,输出缓存只是在内存中保留为响应请求而发送的 HTML 的副本。其后再有请求时将提供缓存的输出,直到缓存到期,这样,性能有可能得到很大的提高(取决于需要多少开销来创建原...

ASP.NET 2.0中使用sitemapdatasource页面导航控件

原文出处:http://www.ad0.cn/netfetch/article.asp?id=285 sitemapdatasource,sitemapdatasource中还可以绑定到不同的其他页面...
  • rtyytr
  • rtyytr
  • 2011年05月23日 10:45
  • 2431

ASP.NET 2.0页面执行顺序

  • 2007年10月08日 08:44
  • 35KB
  • 下载

ASP.NET 2.0 实现伪静态网页方法 3种方法

方法一:利用Httphandler实现URL重写(伪URL及伪静态) 我们有时候会见到这样的地址:“http://www.huoho.com/show-12-34.html”,你或许认为在站点服...

基于ASP.NET 2.0 实现WEB打印方法的探讨

摘  要:Web打印是在开发B/S结构应用程序时一项比较复杂但又应用广泛、非常实用的一种技术。本文主要针对ASP.NET 2.0实现WEB打印的几种方法进行了初步探讨,对每种方法的实现、各自特点进行了...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ASP.NET 2.0中实现跨页面提交
举报原因:
原因补充:

(最多只允许输入30个字)