简介

在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>&nbsp;</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 = "没有找到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

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="javascript: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(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引用来访问源页面中的控件,而先需要将源页面中需要被访问的属性公开出来。同时,建议您只将需要的信息作为公共属性公开,以减少可能被潜在的恶意用户使用的信息。

转载于:https://www.cnblogs.com/superlee/archive/2009/08/03/1537631.html

ASP.NET 2.0中的跨页面提交相关推荐

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

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

  2. ASP.NET 2.0 中实现跨页提交 (碧血黄沙)

    在ASP.NET 2.0中,对于跨页提交已经有了非常合理的解决方案 下面是一个示例: BeginPage.aspx: 请注意Button1的PostBackUrl属性设置 <%@ Page La ...

  3. [导入]ASP.NET 2.0 中实现跨页提交 (碧血黄沙)

    在ASP.NET 2.0中,对于跨页提交已经有了非常合理的解决方案 下面是一个示例: BeginPage.aspx: 请注意Button1的PostBackUrl属性设置 <%@ Page La ...

  4. Asp.NET 2.0中无刷新页面的开发

    .NET 2.0正式版中无刷新页面的开发 在已经发布的 ASP.NET2.0 中,无刷新页面开发相关部分同 beta2 有不少改动.而且在越来越多的 Ajax 开发包被开发出来的情况下, ASP.NE ...

  5. ASP.NET 2.0 中的代码隐藏和编译

    ASP.NET 2.0 中的代码隐藏和编译      Fritz Onion 本页内容 代码隐藏 编译 程序集生成 小结 当我撰写本专栏的时候,Microsoft® .NET Framework 2. ...

  6. 在ASP.NET 2.0中使用样式、主题和皮肤

    ASP.NET 2.0的主题和皮肤特性使你能够把样式和布局信息存放到一组独立的文件中,总称为主题(Theme).接下来我们可以把这个主题应用到任何站点,用于改变该站点内的页面和控件的外观和感觉.通过改 ...

  7. asp.net 2.0中设定默认焦点按钮

    在asp.net 1.1中,当要在page_load页面中,设置某个控件为默认的焦点按钮(也就是默认焦点是在这个控件上的),可能要用到javascript的代码,而在ASP.NET 2.0中,不用这些 ...

  8. 在ASP.NET 2.0中建立站点导航层次

    站点导航提供程序--ASP.NET 2.0中的站点导航提供程序暴露了应用程序中的页面的导航信息,它允许你单独地定义站点的结构,而不用考虑页面的实际物理布局.默认的站点导航提供程序是基于XML的,但是你 ...

  9. asp.net 2.0 中GridView里设置日期格式

    在asp.net 1.0 中的datagrid 中 设置日期字段格式时用 DataFormatString="{0:yyyy-MM-dd}"即可.    在gridview 中设置 ...

最新文章

  1. ajax与axios使用哪个好,ajax、axios、fetch之间的详细区别以及优缺点
  2. scratch学习_学习scratch编程能学到什么?对孩子有帮助吗?
  3. teledb兼容mysql5.7_maridb安装
  4. opencv-原图基础上添加指定颜色
  5. 查询每个用户最后一次登录信息
  6. 单载波DSP模块介绍
  7. centos搭建git服务
  8. MaskedEdit控件
  9. 1095 解码PAT准考证 (25 point(s)) - PAT乙级真题
  10. 文件包含漏洞的审计(审计思路)
  11. mysql之5.7开放远程访问权限
  12. C中error的使用
  13. SQL 2016——新功能
  14. 怎么获取echarts需要的geoJson数据去渲染地图:以广州市白云区24镇街为例(内附资源)
  15. 加拿大高中课程计算机科学,加拿大高中课程
  16. X1000 Kernel 3.10 Linux V8.2编译
  17. 使用lighttpd搭建轻量级web服务器详解
  18. 转自国学大师--南怀谨先生
  19. ProxySQL 配置详解及读写分离(+GTID)等功能说明2 (完整篇)
  20. BI规划落地的正确姿势,五步教你搭建企业级BI项目

热门文章

  1. 3.6 Batch Norm 为什么奏效?
  2. mysql事务与锁_mysql之事务和锁
  3. 云资源中的低成本战斗机——竞价实例,AWS、阿里云等六家云厂商完全用户使用指南
  4. 阿里CTO谈BAT:李彦宏说是新瓶装旧酒、马化腾说太遥远了、马云说今天就应该做
  5. Windows学习总结(19)——Windows必备神器Cmder使用教程
  6. python读取文件并存入mysql_1.python读取txt文件并插入到mysql数据库以及将py脚本文件打包成独立的exe程序...
  7. 老师分身多个教室,教学还有这种神操作?
  8. RxJS 系列之一 - Functional Programming 简介
  9. Redis的安装及原理介绍
  10. 跟着图灵去听课——海底捞敏捷之道纪要