ViewState 如何在不声明的情况下随处访问?

How are ViewStates accessible everywhere without being declared?

我一直认为,要在多个方法中访问一个变量,您要么必须将其声明为 class 成员,要么将其作为参数传递。 但是,我最近正在查看一些示例代码来学习 .NET,并且我遇到了一种叫做 ViewState 的东西。我知道它是为了跟踪一些页面和控件属性,但我不明白它在这里是如何使用的。

代码看起来有点像这样:

private void RowValidating(object sender, EventArg e) {
      ViewState[Backup] = ViewState["TestId"];
      // more code that does not include ViewStates
}


private void UpdateBox() {
     // some code that does not include ViewStates
     int box_id = ViewState[Backup];
     // ...
}

如何随处访问 ViewState?它没有在 class 或任何其他 class 文件中的任何地方声明,并且这个 [Backup] 键只是在没有初始化的情况下创建的。据我所知,在调用 RowValidating 之前,ViewState[Backup] 不存在。

是否可以将ViewState设置为全局变量?还是我总是可以制作自己的密钥,以便在任何地方都可以访问?它看起来像一本字典,但我认为在处理新项目时,符号是 dict.Add(item, value),而不是 dict[item] = value。它必须在某个地方初始化,也许在某个导入的库中?

Session() 和 ViewState 都可以用来在代码中保存值。您不必声明它们,它们内置于 asp.net

的功能中

Session() 是针对每个用户的,因此通常用于保存值甚至在页面之间传递值。但在某些情况下,ViewState 更可取。

因此,例如,如果您有一个产品 ID,甚至可能有您要购买的房子?好吧,如果您打开了两个选项卡,甚至打开了两个不同的浏览器,那么 Session() 将应用于所有打开的浏览器实例。因此,如果用户打开了两个单独的浏览器,那么您在 session() 中保留的“ID”值将适用于两者(因此,请注意,当您打开 3 个浏览器页面并打开 3 个不同的页面时,您要购买哪个房屋 ID房子开着?所以 session() 对用户来说是全局的。

所以说“保留”一行数据以传递到下一个网站 page/form,Session() 可能很棒 - 但请记住,它在所有打开的页面和运行的页面之间共享用户。所以 session() 仍然是每个用户 - 但对那个用户来说是全局的。

Session() 可以是“内存中”的服务器(默认)。但是,如果您使用的是服务器场,那么这些多个服务器中的每一个都不能共享它们的内存,因此您必须采用所谓的 SQL 基于服务器的会话。因此,不是将这些值保存在内存中,而是从存储在 SQL 服务器中的序列化“blob”中洗牌 session() 状态。因此,如果您在像 Azure 这样的基于云的系统上托管您的站点(而不是常规托管),那么 session() 将无法在这些所谓的“大型服务”基础系统上持续存在(或者您正在使用具有负载的服务器场出于可扩展性原因,您有多个服务器托管站点的平衡)。由于托管网站的多个副本可以同时存在,因此需要一种拥有通用 session() 的方法(因此他们将一个 blob 东西推入 SQL 服务器)。所以你仍然可以使用 session(),但它实际上存储在 sql 服务器中。需要注意的是,在某些情况下,基于 SQL 服务器的 session() 会降低性能。高达 10%——或许更多。我发现在大多数情况下,您不会注意到这种性能下降。但它工作无缝(),事实上采用 SQL 基于服务器的会话将意味着 session() 不会由于站点执行错误而经常丢失。我遇到了网站丢失 session() 的各种问题。如果 Web 托管和管理系统使服务器进入休眠状态,甚至发生 .net 代码错误,它可能(并且将会!!)经常导致应用程序池重新启动 - 这会导致 session() 失效(但不会用 SQL 基于服务器的 - 它们坚如磐石)。

ViewState 通常是首选,因为它由每个新网页提供。这 100% 存储在浏览器中。因此,要持久化您即将购买的 houseID 或产品,那么这是按页面发生的,而不是用户使用的所有网页(因此在这种情况下,VieweState 将是更好的选择)。因此,ViewState 由浏览器存储,并且与您在文本框中输入一堆值然后返回 post 时使用的机制非常相似。网页向上传送到服务器 - 页面被处理并发回。但是您会注意到页面上的 MOST 控件保留了它们的值。为了实现这一点,然后使用 ViewState。这适用于隐藏文本框(或隐藏字段 - 与隐藏文本框非常相似)。所以这个加密的 blob 存在于浏览器客户端。因此,这个 blob 事物会伴随 post-backs 和往返以保持这些控制值的完整性。

因此您可以使用 session() 或 ViewState 但是,如前所述,您不想在 ViewState 中填充太多内容,因为它已成为往返生命周期的一部分。但是 ViewState 通常是首选,因为它是按页面操作的。但是,由于每个打开的新浏览器页面都会为每个页面创建一个新的本地 ViewState?然后 ViewState 不能作为一般规则用于在网页之间传递值,如 Session() 可以。

但是,您可以将所有控件的所有值传递到下一页。您可以使用按钮的 post-back URL 来完成此操作。当您这样做时,然后在第一个页面加载时,您可以在加载事件中使用 page.previous 属性。这将使您可以使用上一页中的所有值 - 并且您不需要 Session() 来执行此操作。如果您执行 server.TransferRequest 而不是 Response.Redirect().

,您也可以使用 page.Previous

最后但并非最不重要的一点?你看到很多站点在 URL 中有一大堆参数。所以这个经常被使用,并且有着很长的使用历史。当然,用户可以随意更改这些值 - 但它们仍然经常使用,并且经常使 URL 变得相当丑陋。出于这个原因,我确实喜欢 asp.net 站点,从那时起 URL 就不会在 URL 中公开一堆东西作为参数,并且不会将这些信息放在站点和头脑中。您看到许多购物网站仍在使用 URL 中的参数和值 - 他们这样做是出于可伸缩性的原因 - (他们不必在服务器端存储持久值 - 它可以节省资源)。