【问题标题】:How to not persist in ViewState stuff that doesn't need to be persisted in ViewState?如何不保留不需要在 ViewState 中保留的 ViewState 内容?
【发布时间】:2012-06-26 13:47:43
【问题描述】:

来自微软页面Understanding ASP.NET View State

在页面生命周期的实例化阶段,创建控件层次结构并分配声明性语法中指定的那些属性。由于在构造控件层次结构时,这些声明性属性会在每次回发时自动重新分配,因此无需将这些属性值存储在视图状态中。

这意味着如果您的aspx 文件包含以下标记:

<asp:Label ID="Label1" runat="server" Font-Name="Verdana" Text="Hello, World!"></asp:Label>

必须保留在 ViewState 中的两件事是:

  • 字体名称Verdana
  • 文字Hello, World!

这两个属性不必保留在 ViewState 中,因为它们每次都设置。

另一个不必保留在 ViewState 中的示例是在 aspx 标记文件中声明的项目:

<asp:DropDownList ID="DropDownList1" runat="server">
   <asp:ListItem>One</asp:ListItem>
   <asp:ListItem>Two</asp:ListItem>
   <asp:ListItem>Three</asp:ListItem>
</asp:DropDownList>

DropDownList 项:

  • One
  • Two
  • Three

不必保留在 ViewState 中,因为它们每次都被声明。

这就是我想做的。我希望不必在 ViewState 中保留的东西不要在 ViewState 中保留。相反,的事情必须在 ViewState 中持久化,我希望它们在 ViewState 中持久化。

再次来自 MSDN:

在实例化阶段构建控件层次结构时,Label 的 Text 属性将设置为“Hello, World!”并且它的 Font 属性将其 Name 属性设置为 Verdana。由于这些属性将在实例化阶段的每次页面访问中设置,因此无需将这些信息保存在视图状态中。

一个例子

除了在标记中声明属性之外,想象它们是以编程方式声明的

Label1.Font.Name = "Verdana";
Label1.Text = "Hello, World!";

DropDownList1.Items.Add("One");
DropDownList1.Items.Add("Two");
DropDownList1.Items.Add("Three");

现在为了向 ASP.net 的魔力发出信号,即属性总是在那里,并且不需要在 ViewState,我将在页面初始化期间进行此更改:

protected void Page_Init(object sender, EventArgs e)
{
   //Set properties *before* PageLoad; before the viewstate is read
   //That way the properties will not have to be added to the viewstate
   Label1.Font.Name = "Verdana";
   Label1.Text = "Hello, World!";

   DropDownList1.Items.Add("One");
   DropDownList1.Items.Add("Two");
   DropDownList1.Items.Add("Three");
}

除非那不起作用。即使我在页面周期中足够早地设置控件的属性,并且即使我设置属性每次,ASP.NET 仍然认为它们需要保留在 视图状态

显然我需要我的代码及时运行。从 ASP.NET 认为它仍在读取标记的时候开始。

我如何ViewState 中保留不需要在 ViewState 中保留的东西?

后记

  • 为什么要这样做?只需将其放在标记中

    不能;不是当下拉项来自数据库时

  • 将控件的ViewState属性设置为false

    不能;不会关闭 需要保留在 ViewState

    中的事情

【问题讨论】:

    标签: asp.net viewstate page-init


    【解决方案1】:

    您基本上已经回答了自己的问题。

    对于库存 asp.net 控件,您不能基于每个属性来决定哪些内容保留在 ViewState 中,哪些内容不保留在 ViewState 中。

    如果您滚动自己的自定义控件,则可以通过自定义属性列表等方式获得更多粒度并准确控制哪些属性被存储,哪些不被存储,但是您必须重新创建轮子。

    您可能能够从内置控件继承(我怀疑任何控件是密封的)并覆盖视图状态和/或控件状态处理程序。老实说,这听起来像是一项艰巨的任务。

    我明白您为什么要问 - 为什么不比当前模型更有效。问题是 ASP.NET 从来都不是关于效率的,当然也不是轻量级的。它更多地是以性能和简单性为代价的快速和快速开发 - 只需以 ajax UpdatePanel 设计模式为例。为了便于开发,这是一个完全臃肿的 ajax 实现。

    【讨论】:

    • @antisanity 是的,正如我想说的那样 - 但为什么要重新创建轮子以将 ViewState 减少 50K 字节。梦想?当然可以,但付出的努力却很少。
    • 这似乎是一个从根本上简单的概念;我只是假设 viewstate 会处理这个(特别是因为他们已经竭尽全力决定何时不应包含属性)
    • 50 kB 很容易变成 2 秒的发布时间。当下拉列表中有 200 个国家/地区,GridView 中有 1000 个项目时,事情会变得棘手。
    • @IanBoyd 那么为什么不为您的项目是静态的下拉菜单禁用视图状态呢?
    • @antisanity 不跨回发,不。这就是 ViewState 的目的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多