【问题标题】:asp.net webforms - is this a good way of persisting state?asp.net webforms - 这是保持状态的好方法吗?
【发布时间】:2009-12-09 12:52:56
【问题描述】:

这是一个关于 asp.net WebForms 和 sessionstate 的问题。我知道这可能是 MVC 更好的情况,但我需要使用 WebForms。

在我的页面的 OnLoad 事件中,我初始化了一个对象及其属性(一次调用 db,然后是属性的一些逻辑。)我使用这个对象来填充页面上的控件,例如。 lblTitle.text = myObj.Title.

此页面上还有一个输入文本框,用户将在其中输入一些信息,然后按“保存”按钮。这将调用一个实用函数,它将文本框的内容写入文件并保存。此外,它需要将其保存到名称包含在 myObj.Title 中的文件中。

这是我的问题 - 由于 WebForms 的无状态方面,页面加载后,myObj 消失了。* 这意味着我不能在保存时做这样简单的事情:Util.save(contentsoftextbox, myObj.Title)。

所以我通过在页面的 OnLoad 事件中将 myObj.Title 的值写入会话变量 (Session.Add["title"] = myObj.Title 来解决它。然后当调用保存函数时,我使用这个会话我的第二个参数的变量。

感谢您阅读本文。

我的问题是:

这感觉像是完成工作的一种不必要的复杂方式。是吗?我还能做些什么来完成这项任务?

*对吗?

【问题讨论】:

    标签: asp.net webforms


    【解决方案1】:

    你看过ViewState 吗?如果您只需要访问您所在页面上的对象而不是将其保留在 Session 中,这可能是一个更好的选择吗?

    【讨论】:

      【解决方案2】:

      在大多数情况下,我会在回发时再次重新初始化 myObj。

      【讨论】:

      • 真的吗?再次调用数据库优于会话变量和视图状态?
      • 取决于所涉及物体的重量。 Viewstate 必须序列化为 HTML 源,这会减慢客户端和服务器之间传输数据的加载和回发时间。会话状态使用服务器上的内存,直到会话超时或您明确删除变量。在大多数环境中,数据库调用并没有那么昂贵,因此除非您有大量并发用户流量,否则第二次调用可能没什么大不了的。
      • 同意。物体的大小很重要。但是在考虑性能之前,我发现在 OnLoad 事件中再次运行相同的初始化代码会更容易,如果出现性能问题,我会使用缓存。在这种情况下,由于我在下面的评论中提到的原因,我没有发现视图状态是一个好的缓存(我认为这个缓存的数据不属于客户端),也不是会话状态。
      • +1 好主意 :) viewstate 和 session 都可能很昂贵。如果重新初始化并不昂贵,那么它是一个不错的选择。在视图状态中存储每一件小事也会使页面变得臃肿。
      【解决方案3】:

      这听起来是一个很好的整体方法。我不知道您系统的详细信息,但也许您应该考虑在会话中保存MyObj 而不仅仅是标题。

      【讨论】:

      • 我认为这不是一个好建议。请参阅下面 mfeingold、ScottS、我的答案和 cmets 中的原因:)
      • 我不同意。尽可能少地存储在会话中,因为它会占用服务器上的内存。如果只是文本,请将其存储在查询字符串或单独的 cookie 或视图状态中。
      【解决方案4】:

      你可以把它保存在ViewState

      【讨论】:

      • 感谢您的快速回复。这是保存在会话变量中的首选方法吗?如果有,为什么?
      • 是的,ViewState 会是更好的选择。一个示例可能是拥有一个 GET 变量来控制从数据库加载的 myObj。如果您的浏览器中有两个选项卡,共享会话,但加载了两个不同的 myObj(不同的 id),当您单击按钮时,您将不知道会话中保留了哪个标题。
      • 我仍然希望再次从数据库中加载标题或整个 MyObj,如果这不会产生任何性能问题,我认为通常不会。
      【解决方案5】:

      将相同的值放入 Input type=hidden。这样在回帖上,您将能够从中读回它。

      将此类值放在会话上是一种习惯方式,但由于与在服务器上而不是在浏览器上维护会话状态相关的许多原因,最好避免此类路由,包括但不限于需要会话亲和性(会话 cookie 、粘性会话等)

      【讨论】:

        【解决方案6】:

        注意将对象存储在会话中。如果您不使用 In-proc,则存储在会话中的对象必须是可序列化的,以便它可以扩展。

        另一种选择(如果你想将它存储在客户端并且你不关心对象是否在浏览器中是纯文本的):你可以使用custom properties on your text boxserialize your object/property to JSON使用JavaScriptSerializer

        您可以阅读有关 HTML 5 数据属性的更多信息here

        【讨论】:

          【解决方案7】:

          会话有效,但在服务器群中变得很麻烦。我尽可能避免使用会话。

          我特别不喜欢将会话用于此类特定于页面的事情,因为如果用户从未完成页面上的操作,则该值可能永远不会从会话中删除。系统中有一堆这样的页面,你很快就会有一个非常污染的会话,并且很容易得到作用于会话值的错误,这些错误只是从一些早期操作中遗留下来的。

          Viewstate,将起作用并避免会话问题。

          重新加载时,与页面相关的对象通常是可以接受的,有时出于其他原因需要。重新加载是我首选的“默认”,尽管有些对象可能太昂贵而无法重新加载。

          只需将值放在隐藏字段中,与使用视图状态大致相同。对于像单个标题这样的简单事物,我更喜欢隐藏字段而不是视图状态,因为我喜欢让所有内容尽可能地可读。然而,篡改隐藏字段比篡改视图状态要容易得多,所以如果黑客/安全是一个问题,隐藏字段不是一个好的选择。

          【讨论】:

            猜你喜欢
            • 2011-12-10
            • 1970-01-01
            • 2021-02-08
            • 2011-07-07
            • 1970-01-01
            • 2020-04-20
            • 2017-07-17
            • 1970-01-01
            • 2015-04-28
            相关资源
            最近更新 更多