ASP.NET 2.0中的跨页面提交-阿里云开发者社区

开发者社区> 技术小甜> 正文

ASP.NET 2.0中的跨页面提交

简介:
+关注继续查看
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

打开FirstPage.aspx,输入内容并按下“Postback to Second Page”按钮提交,页面就会提交到SecondPage.aspx,输入的内容也会显示在SecondPage.aspx上。注意FirstPage.aspx中Button2新增的PostBackUrl属性,还有SecondPage.aspx中的@PreviousPageType指令。这些新增的内容,正是ASP.NET 2.0 中的跨页提交的方案的组成部分。
<%@ 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>&nbsp;</p>    
    </div>
    </form>
</body>
</html>
    
大家可能会发现,在使用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 = "没有找到UserName控件。";
}

读取源页面的公共属性
    一旦在目标页面中获取了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则是服务器端的行为。在后面的小节中,我们会分析跨页面提交时客户端浏览器是如何实现提交的。
 
对跨页面提交的简单分析
    在上面的例子中,我们都提到设置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" 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(document.activeElement) == "undefined") {
                    lastFocus.value = options.eventTarget;
                }
                else {
                    var active = document.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" />
总  结
    ASP.NET 2.0 新增的跨页面提交功能,让我们的开发过程有了更加灵活的选择。在使用跨页面提交的时候,我们要根据实际的情况选择合适的方式来读取源页面中的信息。如果源页面与目标页面处于同一个应用程序之内,我们可以选择使用@PreviousPageType指令来指定源页面,这样就可以使用强类型引用的好处。
    由于ASP.NET中的每个页面类所包含的子控件对应的是protected成员,所以您不能直接通过PreviousPage引用来访问源页面中的控件,而先需要将源页面中需要被访问的属性公开出来。同时,建议您只将需要的信息作为公共属性公开,以减少可能被潜在的恶意用户使用的信息。
 
















本文转自terryli51CTO博客,原文链接: http://blog.51cto.com/terryli/519465,如需转载请自行联系原作者


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
遍历获取ASP.NET页面控件的名称及值
逛csdn的时候碰见有人在求助这个问题,特分享一下经验。如果直接用Page.Control 获取的到只是最顶层的页面元素,而真正的拖拉放上去的文本框或Label之类的控件,还隐藏在这些顶层页面元素的里面,所以需要再次遍历。
516 0
在 ASP.NET 页面中使用 TreeView 控件
一、            下载源码 http://www.asp.net/IEWebControls/IEWebControls.exe   二、            安装及编译 1、执行安装文件后,在安装目录找到 “build.bat”文件,用记事本将其打开。
970 0
在两个ASP.NET页面之间传递值
ASP.NET提供了卓越的事件驱动编程模型,让开发者简化了应用程序的总体设计,但是这个也造成了它固有的一些问题,例如,使用传统的ASP里,我们可以通过使用POST方法很容易地实现页面间传递值,同样的事情,在使用事件驱动编程模型的ASP.NET就不是那么容易了,当然了,我们仍然有一些方法可以实现同样的功能。
712 0
Asp.net MVC3 企业网站系统高仿博客园 首页左侧列表页面 实现效果
在前一篇文章Asp.net MVC 3 开发企业网站系统仿照博客园部分功能--总体设计中介绍了数据库的总体设计,现在呢我们就来实现博客园的左侧网站分类效果实现。当然因为我的前端功底实在不敢恭维,所以我采用博客园的CSS和JS脚本,这样我们可以提高网站的实现速度,而不用为了前端的显示界面调整浪费时间(注:前端很重要)。
1147 0
(转)列举ASP.NET 页面之间传递值的几种方式
1.使用QueryString,  如....?id=1; response. Redirect().... 2.使用Session变量。3.使用Server.Transfer。4.Application 。
707 0
+关注
10146
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载