我正在从经典的 ASP 迁移到 ASP.NET,并且遇到了你们许多人已经知道的“视图状态”。我的假设可能会过激,但它看起来非常麻烦。过去我开发了许多 ASP 表单,并且从未遇到过保持状态的问题。有没有其他方法或者我必须在 ASP.NET 中学习这个 Viewstate 的东西?我使用 Visual Studio 2008、VB.NET 作为语言背后的代码,以及带有 SQL Server 2005 的 Framework v3.5。
13 回答
你不必。查看MVC 框架。它消除了 ViewState 并像旧的 ASP 一样工作(至少从这个角度来看)。
我禁用它并在 Page_Init 而不是 Load 中完成大部分工作(由于 ControlState,值仍然保持不变)。这个设置对我来说效果很好。
ViewState 是可选的,但很有帮助。ViewState 是发生在服务器端控件上的所有更改。因此,如果您将文本分配给标签,并且您希望该文本持续存在而不需要在每次回发时重新分配它,那么您将需要维护它。另一个我总是打开 ViewState 的例子是任何数据绑定。
也就是说,出于同样的原因,有时关闭 ViewState 会很有帮助。例如,我总是关闭 ViewState 的一个地方是 MESSAGE 标签。这样,当我必须向用户打印一条消息(一条应该只出现一次然后消失的消息)时,我只需将文本添加到标签中然后忘记它。在下一次 PostBack 期间,标签将自动恢复为在该控件的 ASPX 声明中找到的文本(在本例中为空字符串)。
现在,请注意这与表单集合无关,表单集合是在 PostBack 期间发布到 IIS 的值。表单集合将用户输入的值发送到表单元素(文本框、复选框、下拉列表等)中。这些 .NET 将填充到适当的位置——这发生在处理 ViewState之后。
这样,如果您向客户端发送带有短语“hi there”的文本框,用户将其更改为“See ya”,然后提交表单,那么在 Page_Load 事件触发时文本框将拥有一个文本框TEXT 属性中的“See ya”。
在经典的 ASP 中,我们总是只使用一个 HIDDEN 字段来完成这项工作。Viewstate 只是自动为您执行此操作的一种方式。相信我,学习曲线并不像你想象的那么高。
当您关闭 ViewState 时,某些控件会严重受损,因此请准备好解决这些问题。最简单的做法是懒惰并保持打开状态,但如果不加以检查,ViewState 很容易占 HTML 大小的 30%。
例如,假设您有一个 DropDown,并将其绑定到一个 Fruits 列表。在页面加载的 if(!IsPostBack) { } 块中绑定它。如果关闭 ViewState,单击按钮时将丢失项目。他们需要绑定每个页面加载。您还将丢失您选择的索引,因此您需要将其从 Request.Form[] 变量中移除。
当您使用 ASP.NET 时,Viewstate 是包的一部分。对于基本页面/网站,您不必“知道”如何使用 Viewstate。当您在页面上放置控件时,它就会被使用。
使用 ASP.NET 很难避免 Viewstate,因为即使您在项目级别将其关闭,某些单独的控件仍然使用 Viewstate 来保存其信息。
如果您不想处理 Viewstate,请考虑使用 ASP.NET MVC 框架。您可能会对来自 Classic ASP 的 MVC 框架更满意。
ViewState 在几乎所有情况下都是完全可选的。即使 ViewStateEnabled=false,ASP.NET 也会自动重新填充字段。我使用 ASP.NET 已经 5 或 6 年了,从来没有依赖过 ViewState。我什至尽可能禁用它。
ViewState 在大多数情况下是自动工作的。这就是 ASP.NET 跟踪其所有控件的当前状态的方式。
如果您想存储一些额外的数据,您也可以手动使用视图状态。这很简单:
Viewstate["Key"] = value;
唯一需要注意的是,您存储在视图状态中的任何对象都必须是可序列化的。
我绝对可以建议避免在 DataGrids 和 DropDownLists 中使用 ViewState,因为我自己最近才开始这样做。我这样做不是为了好玩,我必须修复一个已经变得如此之大以至于导致其他问题的页面。但事实证明这很容易,结果如此戏剧性,我很高兴。当然,对于一个小型的简单应用程序或少量数据,这不是必需的,但另一方面,保持一致是件好事(总是从已知到已知,这样您就可以不断改进您的流程......),以及为什么随身携带额外的行李,曾经吗?
这将需要您进行一些手动干预。例如,如果您关闭下拉列表的视图状态,则需要在每次回发时重新绑定它们,然后从 Request 对象中恢复 SelectedValue。你需要阅读这个,但谷歌有很多现成的信息。
对于“植根”到页面的 asp.net 控件,视图状态会自动保留。您几乎不需要做任何事情,值和其他一些信息在隐藏输入 B64 编码中传递。如果你愿意,你可以看它,但没关系,这一切都是为你自动处理的。
如果您正在为自己的消费编写代码,您可以将其关闭而不必担心。
假设您要维护其他人编写的 Web 窗体代码,因此您应该知道配置选项和痛点是什么。我能想到的前几名
- 如何在站点、页面和控制级别禁用它
- 为什么 MachineKey 与网络农场相关
- 为什么您的事件日志充满了 ViewStateAuthentication 错误
- ViewStateUserKey 是什么
就实际学习曲线而言,这可能是对几篇 MSDN 文章的透彻阅读。
ViewState 是 Web 表单隐喻固有的必要邪恶。我个人认为这种方法已经过时、臃肿而且通常对网络不友好。最好按照上面的建议检查 MVC 框架。
我建议您避免使用 ViewState 作为“缓存”来来回传递数据的诱惑(我已经看到网站这样做是因为集群设置和没有 SQL 支持的会话状态)。数据被序列化并添加到页面中,并且必须在每个请求中进行往返,这会增加页面的总大小并使您的站点加载速度变慢。
'<%@ Control Language="C#" AutoEventWireup="true" CodeFile="HomePage.ascx.cs" Inherits="HomePage" %>
<script runat="server">
void testHF_ValueChanged(object sender, EventArgs e)
{
this.HFvalue.Text = this.testHF.Value ;
}
</script>
<asp:Label ID="UserNamelbl" runat="server" Text="User Name : " Visible="false"></asp:Label>
<asp:TextBox ID="UserNametxt" runat="server" Visible="false" ></asp:TextBox>
<asp:Label ID="HFvalue" Text="......" runat="server"></asp:Label>
<asp:HiddenField ID="testHF"
OnValueChanged="testHF_ValueChanged"
value=""
runat="server" ></asp:HiddenField>
<input type="submit" name="SubmitButton" value="Submit" onclick="CL()" />
<script type="text/javascript">
function CL()
{
this.testHF.Value = this.UserNametxt.Text;
}
</script>
'