在asp中使用Viewstate的目的是什么?净

时间:2017-06-07 01:31:40

标签: asp.net

据说Viewstate用于在请求之间保留状态,但让我们有这样的场景: 我有一个以0开头的文本框,以及一个增加+1的按钮。以下是步骤:

  1. 最初是获取页面的get请求,因此文本框中的文本为0。

  2. 我点击了按钮,值0正在回发到服务器。

  3. 服务器上事件处理程序中的方法将值递增1,然后将值1发送到我的浏览器。

  4. 现在我的浏览器的文本框中显示1,我再次点击该按钮,1再次发送到服务器

  5. 与步骤3相同,然后我会在文本框中显示2个。

  6. 正如您所看到的,我不需要使用Viewstate来“记住”上一个请求中的值,我知道asp.net中的文本框默认使用Viewstate,即使enableviewstate设置为false,所以只需忽略它,在我的例子中使用viewstate的目的是什么?

1 个答案:

答案 0 :(得分:4)

题外话:

请注意,您正在询问ASP.NET WebForms,现在已经有效地弃用了它。它是ASP.NET中的一个抽象层,旨在通过模仿VB6和WinForms如何工作来简化设计stateful数据输入网页(" Web表单")(使用& #34;服务器端事件"和#34;控件"),但是当你需要对Web应用程序进行精确控制时这是一个非常leaky abstraction,这就是为什么WebForms不是今天很受欢迎,以及ASP.NET MVC取代它的原因(以及WebForms isn't even supported by ASP.NET Core(以前称为ASP.NET 5))。

返回主题:

正如您所观察到的那样,直接POST回服务器的值(因为它们位于<input />元素内部)根本不会从ViewState中受益 - 但是ASP.NET WebForms&#39 ;控件具有许多属性和值,这些属性和值不会包含在自己的<input />元素中,例如(例如)<asp:Label>&#39; Text=""属性:

我将说明:

MyPage.aspx:

<form runat="server">
    <p>Name: <input runat="server" id="name" type="text" /></p>
    <p>Special message: <asp:Label runat="server" id="message" /></p>
    <asp:Button runat="server" id="submit" text="Set name" />
    <asp:Button runat="server" id="somethingElse" text="Submit form" />
</form>

MyPage.aspx.cs(&#34; code-behind&#34; page):

protected override void submit_ServerClick(Object sender, EventArgs e) {

    this.message.Text = "Congratulations to " + this.name + ", our 1,000,000th customer!"; // https://www.youtube.com/watch?v=suyQ44rRL5M
    this.name.Text = "";
}
  1. 如果用户在<input id="name" />文本框
  2. 中输入了他们的名字
  3. 然后点击&#34;设置名称&#34;按钮
  4. 然后他们的名字会出现在<asp:Label id="message" />
  5. (代码也清除了名称输入)
  6. 然后,如果用户点击&#34;提交表单&#34;如果按钮没有再次输入其名称,<asp:Label />将保留显示的消息 - 即使他们的名字从未出现在任何<input />元素中!
  7. 这是有效的,因为标签的文本实际上是重新提交在隐藏的__VIEWSTATE值中,并且页面被重建(在ASP.NET内部的幕后),因为它是再次渲染。

    以下是另一种观察方式:

    C > S : client-to-server (web-browser to web-server)
    S > C : server-to-client (web-server response to user's browser)
    
    C > S - GET /MyPage.aspx (no form data)
    S < C - OK                name="", __VIEWSTATE=""
    C > S - POST /MyPage.aspx name="Foo", __VIEWSTATE=""
    S < C - OK                name="", __VIEWSTATE="message.Text:\"Congratulations to foo, our 1,000,000th customer!\""
    C > S - POST /MyPage.aspx name="", __VIEWSTATE="message.Text:\"Congratulations to foo, our 1,000,000th customer!\""
    S < C - OK                name="", __VIEWSTATE="message.Text:\"Congratulations to foo, our 1,000,000th customer!\""
    

    即使name=""字段在设置后被清除,原始提供的值(&#34; foo&#34;)也会保留在__VIEWSTATE字段中。

    请记住,就客户端Web浏览器而言,__VIEWSTATE是一个不透明的blob:它是HMAC签名的Base64编码的字符串,消费者无法解码或读取,只能由服务器解码或读取。开发人员还可以启用__VIEWSTATE值的加密(尽管默认情况下应该已启用,IMO)。它的工作方式与包含安全令牌的HTTP cookie类似。 (ViewState与Cookie不兼容,因为它特定于单个页面,而不是HTTP会话,并且它通常可以达到兆字节中的大小,这对于cookie来说太大了)。

    我觉得WebForms是一个有趣的网络实验 - 但它增加了很多复杂性,这可能是不必要的,WebForms应用程序本质上是非RESTful的,这打破了我们现在认为理所当然的关于网络的许多假设 - 例如,它几乎不可能通过简单的请求自动化Web应用程序(例如,您需要重放每个中间视图状态变异请求),并且如果资源只能通过WebForms回发访问(例如,因为&#34;服务器端事件处理程序&#34;)然后它会破坏书签。一个特别令人震惊的罪是使用<asp:Hyperlink>根本不是<a href="">,而是会导致POST后跟HTTP重定向(通过链接中的Response.Redirect&# 39; s&#34;服务器端点击&#34;事件处理程序)。