【问题标题】:HttpContext.Current.Session in a Shared method isn't persisting changesShared 方法中的 HttpContext.Current.Session 没有持久化更改
【发布时间】:2017-04-24 02:34:42
【问题描述】:

我在 System.Web.UI.Page 中使用一些 WebMethods 来处理一些 ajax 请求,并且我试图在会话中存储一个对象以跨多个 ajax 请求保留信息,甚至在离开页面后回来了。

我通过HttpContext.Current.Session("foo")访问会话,如果是Nothing,我通过HttpContext.Current.Session("foo") = New Bar()设置它。

我遇到的问题是,在设置后,下次我点击该方法时,它已被重置。我尝试更改在其他地方设置的其他一些会话变量,它们也被还原。这告诉我我正在获取会话状态的副本,而不是我可以更新并导致从请求到请求持续存在的引用。我仔细检查了 WebMethod 的 EnableSession 属性是否为 True,但仍然没有保留对会话状态的更改。

方法声明:

<System.Web.Services.WebMethod(EnableSession:=True)>
Public Shared Function foo(ByVal woNum As String, ByVal workCenter as String) As ToolingModel
    Return ToolingModel.getSessionTooling(woNum, workCenter)
End Function

getSessionTooling:

Public Shared Function getSessionTooling(woNum As String, workCenter As String) As ToolingModel
    Dim tooling As ToolingModel = HttpContext.Current.Session(TOOLING_MODEL_SESSION_KEY)

    If tooling Is Nothing Then
        tooling = New ToolingModel(woNum, workCenter)
        HttpContext.Current.Session(TOOLING_MODEL_SESSION_KEY) = tooling
    ElseIf tooling.woNum <> woNum OrElse tooling.workCenter <> workCenter Then
        tooling.woNum = woNum
        tooling.workCenter = workCenter
        tooling.assets.Clear()
    End If

    Return tooling
End Function

如何让我的更改应用于持久会话状态,从共享 WebMethod 访问它?

编辑:发现我的问题,一个星期太晚了。 .aspx 的第 1 行:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="foo.aspx.vb" 
    Inherits="foo" MaintainScrollPositionOnPostback="true" 
    MasterPageFile="~/mstrFoot.master" EnableSessionState="ReadOnly" %>

页面被设置为只读会话,它会覆盖 PageMethod 的 EnableSession 设置。 [捂脸]

【问题讨论】:

  • 你也可以发布函数声明吗?如果添加正确的属性,它看起来应该可以工作:stackoverflow.com/questions/4758575/…[WebMethod(EnableSession = true)]
  • 会不会是配置问题?也许 POST 与 GET 有问题?当用户登录时,我们设置了一堆会话变量并且它们保持得很好,但是如果我在这里进行更改,我无法对会话进行更改。
  • 您使用的 .net 版本是什么,以便我可以更准确地进行测试?
  • 这解决了我的问题

标签: vb.net session-state webmethod


【解决方案1】:

默认情况下,IIS 将利用多核 CPU。在多处理器环境中,web.config 中的默认 InProc SessionState 设置随机处理不同线程(每个处理器/内核的单独线程)上的请求。更多细节在这里:https://msdn.microsoft.com/en-us/library/ms998549.aspx#scalenetchapt06_topic8

仅供参考,虽然我过去自己也做过这件事,但在对 Web API (SOAP/REST) 的请求之间维护会话状态是不受欢迎的,因为它代表了难以扩展的服务器开销。在会话状态中存储复杂对象还需要该对象/属性/字段的各个方面也可以序列化,这可能会变得非常棘手。那就是……

根据您提供的信息,您需要将 Web 应用设置为使用 StateServer 模式并在某些机器上启用 ASP.NET 状态服务,以便由不同线程处理的多个请求将保持跨 CPU 的会话。 https://msdn.microsoft.com/en-us/library/ms178586.aspx

【讨论】:

  • SessionState 当前设置为 SQLServer 模式,这和 StateServer 完成的一样吗?
  • 如果您已验证会话正在持久化到 SQL Server,那么是的,这与 StateServer 完成相同的事情。您可能还必须为您的自定义对象实现自定义序列化。阅读本文的“进程外”会话以确保您的自定义对象将被正确序列化/反序列化:hanselman.com/blog/…
【解决方案2】:

如果您的会话没有超时,最可能的原因是 ASP.NET 在您的 webmethod 请求和(aspx?)页面调用之间生成了不同的 sessionID。您可能在两个 Web 方法调用之间有相同的会话可用(如果没有超时并且启用了 cookie),但在页面调用和 Web 方法之间却没有。

Cannot get session in webmethod in asp.net

【讨论】:

  • 我可以从会话中获取会话变量(例如用户名、电子邮件地址等),这些变量是在应用程序的其他位置设置的,但我在 WebMethod 中所做的任何更改都不会保留。
  • getSessionTooling 是在哪里定义的?您没有将 httpcontext 传递给该方法,它可能没有为请求获取正确的 httpcontext。尝试将上下文传递给方法调用。
  • 它在我的ToolingModel 类中定义。我确实尝试过从 WebMethod 传入 Session,但我遇到了同样的问题,即会话没有保留更改。
  • 您查看我发布的链接了吗?验证您在不同请求之间是否具有相同的 Session ID?
  • 我刚刚检查过,我在不同的请求之间得到了相同的会话 id,甚至在不同的页面和 WebMethod 与 Page_Load 之间也是如此。
猜你喜欢
  • 1970-01-01
  • 2018-01-14
  • 1970-01-01
  • 2021-08-01
  • 2011-05-31
  • 2011-05-06
  • 1970-01-01
  • 2014-09-02
  • 2016-12-31
相关资源
最近更新 更多