据说Viewstate用于在请求之间保留状态,但让我们有这样的场景: 我有一个以0开头的文本框,以及一个增加+1的按钮。以下是步骤:
最初是获取页面的get请求,因此文本框中的文本为0。
我点击了按钮,值0正在回发到服务器。
服务器上事件处理程序中的方法将值递增1,然后将值1发送到我的浏览器。
现在我的浏览器的文本框中显示1,我再次点击该按钮,1再次发送到服务器
与步骤3相同,然后我会在文本框中显示2个。
正如您所看到的,我不需要使用Viewstate来“记住”上一个请求中的值,我知道asp.net中的文本框默认使用Viewstate,即使enableviewstate设置为false,所以只需忽略它,在我的例子中使用viewstate的目的是什么?
答案 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 = "";
}
<input id="name" />
文本框<asp:Label id="message" />
<asp:Label />
将保留显示的消息 - 即使他们的名字从未出现在任何<input />
元素中!这是有效的,因为标签的文本实际上是重新提交在隐藏的__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;事件处理程序)。