您的位置:首页 > 编程语言 > ASP

ASP.NET 状态管理(查询字符串 和 跨页回发)

2012-07-12 17:48 423 查看
视图状态一个最大的限制是它必须和特定页面紧密绑定。当用户从一个页面浏览到另一个页面时,这些信息也就消失了。这个问题有几种解决方案,最佳的方案取决于你的项目需求。

查询字符串

一个常用的办法是在URL中使用查询字符串传送信息。搜索引擎中频繁的使用了这种办法。


http://www.google.ca/search?q=organic+gardening


查询字符串的优势:

它是轻量级的,并且不会加重服务器的负担。和跨页回发不同,查询字符串很容易在页面间传送相同的信息

查询字符串的限制:

信息仅限于简单的字符串,只能包含合法的URL字符

用户很容易看到信息,对因特网上的窃听者也是如此。

大胆的用户可能会修改查询字符串或给它赋新值,而你的程序并不能预期和预防这些修改。

多数浏览器对URL字符串的长度有限制(通常1K-2K)

尽管如此,把信息加入到查询字符串中仍是一项很有用的技术

使用查询字符串

没有基于集合的方式来帮助你放置信息,你需要自己放置查询字符串的存储信息。


intrecordID=10;

Response.Redirect("newpage.aspx?recordID="+recordID.ToString());

可以发送多个参数,中间用符号&隔开


接收页面很容易就可以使用查询字符串来工作,它使用内置的Request对象提供的QueryString字典集合来取值:


stringID=Requet.QueryString["recordID"];

如果集合中不包含查询的Key值,那么ID将被设为null值

取得的值总是字符串,也因此很容易就可以转换为其它数据类型。



URL编码

查询字符串的一个潜在问题是使用URL中不允许的字符(URL中所有字符必须是字母、数字、及少量的符号"$-.+!*'(),")。如果担心将要在查询字符串中保存的数据含有非法字符,可以使用HttpServerUtility类中提供的方法进行编码。


stringproductName="FlyingCarpet";

Response.Redirect("newpage.aspx?productName="+Server.UrlEncode(productName));

可以使用Server.UrlDecode()方法将字符串恢复其初始值,但不需要这么做,当使用Request.QueryString集合时,ASP.NET自动解码了该值。



跨页回发

只不过是把信息从一个页面发送到另一个页面去,这个技术听起来很简单,但却是一个潜在的雷区!使用的不好,会导致创建的页面紧密耦合而难于改进和调试。

支持跨页回发的基础架构是属性PostBackUrl,它在IButtonControl接口中定义并在按钮类控件(Button、LinkButton、ImageButton)中出现。只需要简单地将PostBackUrl设置为其他Web窗体的名字就可以使用跨页回发了。

看下面的小示例:

<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="CrossPage1.aspx.cs"Inherits="Chapter06_CrossPage1"%>




<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">




<htmlxmlns="http://www.w3.org/1999/xhtml">


<headrunat="server">


<title>CrossPage1</title>


</head>


<body>


<formid="form1"runat="server">


<div>


<asp:TextBoxID="txtFirstName"runat="server"></asp:TextBox>


 <asp:TextBoxID="txtLastName"runat="server"></asp:TextBox>


 <asp:ButtonID="btnSubmit"runat="server"PostBackUrl="CrossPage2.aspx"


Text="Submit"/>


</div>


</form>


</body>


</html>


CrossPage2.aspx可以通过PreviousPage属性和CrossPage1.aspx中的对象进行交互:

protectedvoidPage_Load(objectsender,EventArgse)


{


if(Page.PreviousPage!=null)


{


lblInfo.Text="Youcamefromapagetitled"+PreviousPage.Header.Title;


}


}


1.获取页面特定信息

在先前的示例中,仅仅是获得了Page类的成员。如果要得到更具体的细节,如控件的值,必须把PreviousPage转换为适当的类型:

protectedvoidPage_Load(objectsender,EventArgse)


{


Chapter06_CrossPage1prePage=PreviousPageasChapter06_CrossPage1;


if(prePage!=null)


{


//(Readsomeinfomationfrompreviouspage.)


}


}


注:

对于没有项目文件的网站,VS会标记为错误,表示它没有源页面类的类型信息(如CrossPage1),不过编译后这个错误会消失

即便已经将前一页面转换成了正确的页面类型,但还是不能够直接访问控件的值。这是因为控件被声明为了受保护的成员,此时,可以通过在页面类中添加封装控件变量的属性来实现上述操作:

publicTextBoxFirstNameTextBox


{


get{returntxtFirstName;}


}




publicTextBoxLastNameTextBox


{


get{returntxtLastName;}


}


但这不是好的方式,它显示了太多的细节,还允许目标页面随意访问控件的任意属性!最好的方式是定义特定且有效的方法或属性来提取需要的信息:

publicstringFullName


{


get{returntxtFirstName.Text+txtLastName.Text;}


}


现在已经达到最好的状态了。两个页面的关系被文档化且易于理解。即使源页面控件改变了,仍只需要修改FullName属性,修改仅限于CrossPage1.aspx页面,而完全不需要修改CrossPage2.aspx页面

2.在任意事件处理程序中进行跨页发送

除了使用实现了IButtonControl接口的那些按钮进行跨页发送外,我们还可以使用一个重载的Server.Transfer()方法将试图状态信息完整的送到目标页面。只要简单的加上一个值为true的oreserverFrom参数即可。

//为true,则保留System.Web.HttpRequest.QueryString和System.Web.HttpRequest.Form集合。


//为false,则清除System.Web.HttpRequest.QueryString和System.Web.HttpRequest.Form集合。


Server.Transfer("CrossPage2.aspx",true);


这样就可以在网页代码的任意地方使用跨页发送了(只要能访问到Server对象的地方)。

该技术会造成服务器的重定向,这意味着没有额外的往返来重定向客户,即使已去了另一个页面,但客户端浏览器中的URL不会改变。

怎么区分是通过一个按钮跨页传送还是通过Server.Transfer()方法跨页传送的呢?

protectedvoidPage_Load(objectsender,EventArgse)


{


if(PreviousPage==null)


{


//直接被get或post方式请求


}


elseif(PreviousPage.IsCrossPagePostBack)


{


//通过Button类跨页回传


}


else


{


//通过Server.Transfer()跨页回传


}


}


3.IsPostBack属性和IsCrossPagePostBack属性

理解Page.IsPostBack属性在跨页回送中是很重要的。源页面(触发了跨页回送的页面)的IsPostBack属性为true。目的页面(接收跨页回送的页面)的IsPostBack属性为false。这个系统的好处是,它意味着你的初始化代码通常会在该运行的时候运行

假设第一次请求CrossPage1.aspx使用如下代码时,它执行了一些费时的初始化工作:

protectedvoidPage_Load(objectsender,EventArgse)


{


if(!Page.IsPostBack)


{


//Retrievesomedatafromadatabaseanddisplayitonthepage.


}


}


现在假设用户通过跨页回送从页面1转到了页面2。只要CrossPage2.aspx方位PreviousPage属性,就会执行CrossPage1.aspx页面生命周期。此时,再次触发CrossPage1.aspx的Page.Load事件。然而,CrossPage1.aspx上的Page.IsPostBack属性为true,你的代码就会跳过费时的初始化步骤,控件的值从视图状态得以恢复。另一方面,CrossPage2.aspx的IsPostBack属性为false,所有该页面执行必要的第一次初始化。

在某些情况下,当页面不是跨页回送的源页面时,你可能会有用于处理第一次请求和所有接下来的回送的代码。在这种情况下,你可以查看IsCrossPagePostBack属性,如果当前页面触发了一个跨页回送,则该属性的值为true。

protectedvoidPage_Load(objectsender,EventArgse)


{


if(Page.IsCrossPagePostBack)


{


//ThispagetriggeredapostbacktoCrossPage2.aspx.


}


elseif(Page.IsPostBack)


{


//Thispagewaspostedbacknormally.


//Don'tdothefirst-requestinitialization.


}


else


{


//Thisisthefirstrequestforthepage.


//Performalltherequiredinitialization.


}


}


4.跨页发送和验证

在跨页回送中使用验证有一些潜在的麻烦。如果源页面包含验证控件,那么使用跨页发送会发生什么呢?





两个按钮都将CausesValidation设置为true,因此单击任何一个按钮来触发跨页回发,回发都会被浏览器的客户端验证阻止,并出现错误信息。此时将RequiredFieldValidator验证控件的属性EnableClientScript设为false以模拟客户端不支持JavaScript脚本或恶意客户避开了客户端验证,再次单击任一按钮,页面回发,此时新页面出现了。

为了避免发生这种问题,显然,在执行任意动作前必须检查Page.IsValid以在目标页面中保证源页面有效。这是需要验证的Web窗体的标准防范。不同的是,当页面无效时什么都不做事不够的,我们往往需要采用一些步骤将用户带回到原始页面

//Thiscodeisintargetpage.


protectedvoidPage_Load(objectsender,EventArgse)


{


if(PreviousPage!=null)


{


if(!PreviousPage.IsValid)


{


//Displayanerrormessageorjustdonothing.


//Response.Redirect("CrossPage1.aspx");


}


else


{


//...


}


}


}


上面这段代码还可以再度改进。现在,因为页面是被重新请求的(不是回发),所有当用户回到原始页面时,错误信息不回出现。要修正这个问题,可以设置一个标记让原始页面知道,请求已被目标页面拒绝。

protectedvoidPage_Load(objectsender,EventArgse)


{


if(PreviousPage!=null)


{


if(!PreviousPage.IsValid)


{


//UrlReferrer:获取有关客户端上次请求的URL的信息(包含许多信息)


//AbsolutePath:获取URI的绝对路径


Response.Redirect(Request.UrlReferrer.AbsolutePath+"?err=true");


}


else


{


//...


}


}


}


现在,原始页面只需要检查查询字符串中的标记并再次执行验证,验证将显示无效数据的信息。

protectedvoidPage_Load(objectsender,EventArgse)


{


if(Request.QueryString["err"]!=null)


{


Page.Validate();


}


}


还可以做更多来改进页面。比如说,用户已经填写了某一详细表单的一部分,这时候再重新请求页面就不太好,因为这样就清空了用户的输入,用户将不得不重新开始。你应该在响应流中写一些JavaScript代码,它使用浏览器的回退功能回到源页面。

这个示例演示了跨页回发通常要比开发人员想象的麻烦。如果没有小心处理,跨页回发会导致生成紧耦合的页面,它们相互有依赖性,这使得它们将来的修改变得困难。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐
章节导航