我在System.Web.UI.Page中使用一些WebMethod来处理一些ajax请求,我正在尝试在会话中存储一个对象,以便在几个ajax请求之间保留信息,甚至在离开页面之后返回。
我正在通过HttpContext.Current.Session("foo")
访问会话,如果没有,我通过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设置。的 [捂脸]
答案 0 :(得分: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
答案 1 :(得分:1)
如果您的会话没有超时,最可能的原因是ASP.NET在您的webmethod请求和您的(aspx?)页面调用之间生成不同的sessionID。您可能在两个Web方法调用之间有相同的会话(如果没有超时并启用了cookie),但在页面调用和web方法之间没有。