.net 在处理单个页面时,ViewState是比QueryString更好的维护状态的选择。为什么?

.net 在处理单个页面时,ViewState是比QueryString更好的维护状态的选择。为什么?,.net,asp.net,asp.net-mvc,.net,Asp.net,Asp.net Mvc,我正在读这篇文章: 史蒂文A.史密斯(他不是ESPN的节目主持人吗?) 在这篇文章中,Steven发表了以下声明:“在处理单个ASP.NET页面时,ViewState是比QueryString更好的维护状态的选择” 不幸的是,他没有解释为什么会这样。为什么会这样?我可以想象,因为查询字符串是页面URI的一部分,因此可以被用户篡改。更不用说QueryString中的空间是有限的——仅限于URL的最大大小(IE中为2048字节,其他浏览器更适合) 除了篡改之外,在QueryString中存储随机的状

我正在读这篇文章: 史蒂文A.史密斯(他不是ESPN的节目主持人吗?)

在这篇文章中,Steven发表了以下声明:“在处理单个ASP.NET页面时,ViewState是比QueryString更好的维护状态的选择”


不幸的是,他没有解释为什么会这样。为什么会这样?

我可以想象,因为查询字符串是页面URI的一部分,因此可以被用户篡改。更不用说QueryString中的空间是有限的——仅限于URL的最大大小(IE中为2048字节,其他浏览器更适合)


除了篡改之外,在QueryString中存储随机的状态位会导致非常丑陋的URL,从而导致对搜索引擎不友好的URL。

Erik是正确的,但我还要补充一点,在ASP.NET中,ViewState被序列化为一个隐藏的表单元素。其思想是,您可以在ViewState中存储任何对象(即使是复杂的对象),它们将自动序列化,而在QueryString中存储此类对象通常意味着手动解构它们并编写某种解析器来重新构建它们。

事实并非如此

ViewState存储在页面本身的隐藏表单字段中。这是很有用的,在状态实际上是暂时的情况下(WebForms默认情况下依赖于它来控制状态),但它在页面加载中实际保持的唯一方法是每次向服务器发出请求时强制回发

查询字符串是URL的一部分-更改查询字符串会更改URL。请求在URL中存储页面状态的URL将保留该状态。因此,即使在会话之间或在用户之间,也有可能保留状态-URL可以添加书签,稍后再次请求,通过电子邮件发送等。当然,此状态作为单个URL的一部分附加到单个页面-如果另一个页面需要它,则必须手动传输(通过为该页面添加查询字符串)或者通过其他方式(cookies、POST数据、服务器端会话数据)。当然,如果你不想在时间和空间上保持状态。。。或者你的州很大。。。查询字符串不合适

请注意,逻辑上,查询字符串中存储的ViewState和state都是特定于页面的;尽管它们可以作为GET(查询字符串)或POST请求(ViewState)的一部分前置到另一个页面,但浏览器本身不会将它们与单独页面的请求相关联,也不会在返回到上一个页面时更新这些状态。ViewState(as)提供的少量额外安全性可能就是史密斯先生建议将用户特定状态存储在单个页面上的原因。然而,为了让它们跨页面工作,这种每页附件通常会使cookie(或由客户端cookie索引的服务器端会话状态)更适合保存特定于给定用户或会话但不特定于任何单个页面的状态


就个人而言,我从未发现ViewState特别有用——它很脆弱,并且对如何执行导航设置了严格的限制。但是,如果您坚持使用纯WebForms回发/重定向模型,则可以使其有效工作(因为该框架将为您处理大多数难看的细节)。请注意,尝试在单个页面上执行过多操作可能会导致大量的ViewState,并相应地降低用户的加载/重新加载时间。

我注意到您已将ASP.NET MVC包含在这个问题的标记中。您应该知道ASP.NET MVC没有ViewState。完全可以。

这要看情况而定

查询字符串中的项目可以进行深度链接。您可能不希望这样,或者可能需要编写代码

查询字符串的长度有限。并不是说有人应该在他们的viewstate中设置10K,而是我在需要时在viewstate中的查询字符串上设置了超过2k的限制*。这不是你用QyeryString能做的事

在大多数情况下,您应该将两者结合使用。有了MVC,您将失去ViewState,但在某些情况下可能会开发出自己的类似解决方案

编辑: *不同的浏览器支持不同的最大长度,但仍然是一个问题。

我想你已经列出了(大部分)最重要的原因+幸运的是,史蒂文A.史密斯并不像我想象的那样在全球独一无二。但是我写了那篇文章,Erik很好地描述了为什么ViewState可以在单个Web表单页面中做得更好。这篇文章早于MVC,并且假设您使用的是对页面的回发,正如其他人所写的,如果您使用的不是ViewState,那么您最终将复制ViewState为您所做的一些工作(解析、存储、重新水化等).这是真的-尽管你可以通过使用自己的隐藏字段来维护状态来恢复它=X