ASP.NET 页面传输与数据传递的改进方法

在开发ASP.NET应用程序时,经常使用跨页面发布来传递页面数据。跨页面发布的优势在于,被传输的页面可以访问前一个页面以检索页面数据,这减少了会话管理的成本。因此,更倾向于使用跨页面发布。但是,跨页面发布有一个不喜欢的地方,那就是它不能在事件处理器中执行。当设置按钮的PostBackUrl属性以执行跨页面发布时,不幸的是,点击事件处理器不会工作。因此,如果想在事件处理器中执行某些操作后转移到另一个页面,不能使用跨页面发布。

因此,当使用跨页面发布时,必须使用几种实现技术。在某些情况下,必须设置PostBackUrl属性以执行跨页面发布。在其他情况下,必须实现一个事件处理器,以便在执行某些操作后使用Response.Redirect方法转移到另一个页面(尽管也可以使用HttpServerUtility.Transfer方法,但不想使用它)。此外,然后,必须使用会话或查询字符串将数据传递到另一个页面。

因此,页面传输和数据传递的实现变得复杂。为了减轻这种复杂性,想出了一种机制,可以在事件处理器中执行跨页面发布。它总是允许使用跨页面发布将数据传递到另一个页面。

概念

想法的概念如图1所示。

图1. 想法的概念。

想法的主要点如下:

  • 使用异步回传来请求服务器
  • 将跨页面发布脚本作为异步回传的响应返回
  • 评估返回的脚本
  • 使用PreviousPage属性检索前一页数据

当异步回传完成时,将引发ScriptManager.endRequest事件。因此,此事件允许在客户端完成异步回传后执行额外的处理。

ClientScriptManager.GetPostBackEventReference方法允许在服务器端事件处理器中创建跨页面发布脚本。当传递一个适当设置的PostBackOption类的实例时,此方法会返回一个跨页面发布脚本作为字符串。

ScriptManger.RegisterDataItem方法可以用来将创建的脚本作为响应返回。此方法允许将任何数据存储在dataItems数组中。并且,dataItems数组可以在endRequest事件处理器中访问。

在endRequest事件处理器中,可以通过dataItems数组检索返回的跨页面发布脚本。当将脚本传递给eval方法时,将执行跨页面发布。

像普通的跨页面发布一样,可以使用PreviousPage属性从下一页访问前一页数据。自然地,PreviousPageType指令也有效。

实现示例

以下是Page1.aspx的部分代码:

<body> <form id="form1" runat="server"> <asp:ScriptManager ID="scriptManager" runat="server" /> <asp:UpdatePanel ID="updatePanel" runat="server"> <ContentTemplate> <asp:Button ID="submitButton" runat="server" Text="Submit" OnClick="Submit" /> </ContentTemplate> </asp:UpdatePanel> </form> </body>

以下是Page1.aspx.cs的部分代码:

using System; using System.Text; using System.Web; using System.Web.UI; namespace SampleCode { public partial class Page1 : Page { public string OrderNo { get { return (string)ViewState["OrderNo"]; } private set { ViewState["OrderNo"] = value; } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); StringBuilder script = new StringBuilder(); script.Append("var manager = Sys.WebForms.PageRequestManager.getInstance();"); script.Append("manager.add_endRequest(function(sender, args) {"); script.Append("if (args.get_error() == undefined) {"); script.Append("var dataItems = args.get_dataItems();"); script.Append("var item = dataItems['" + ClientID + "'];"); script.Append("if (item != undefined) {"); script.Append("eval(item);"); script.Append("}"); script.Append("}"); script.Append("});"); ClientScript.RegisterStartupScript(GetType(), "doCrossPagePostBack", script.ToString(), true); } protected void Submit(object sender, EventArgs e) { Random r = new Random(); OrderNo = String.Format("OD{0:00000000}", r.Next(0, 99999999)); NavigateTo("~/Page2.aspx"); } private void NavigateTo(string url) { ScriptManager manager = ScriptManager.GetCurrent(this); if (manager.IsInAsyncPostBack) { if (VirtualPathUtility.IsAbsolute(url) == false) { url = VirtualPathUtility.ToAbsolute(url); } PostBackOptions o = new PostBackOptions(this, String.Empty, url, false, false, false, true, false, String.Empty); manager.RegisterDataItem(this, ClientScript.GetPostBackEventReference(o)); } } } }

以下是Page2.aspx的部分代码:

<body> <form id="form1" runat="server"> <asp:Label ID="orderNoLabel" runat="server" Text="Order No :" /> <asp:Label ID="orderNoValueLabel" runat="server" /> </form> </body> using System; using System.Web.UI; namespace SampleCode { public partial class Page2 : Page { protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (PreviousPage != null && PreviousPage.IsCrossPagePostBack) { Page1 previousPage = (Page1)PreviousPage; this.orderNoValueLabel.Text = previousPage.OrderNo; } } } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485