2016-12-08 25 views
5

我使用一些的WebMethods在System.Web.UI.Page來處理一些Ajax請求,和我試圖存儲對象的會話在多個ajax請求中保留信息,甚至在離開頁面並返回之後。HttpContext.Current.Session在一個共享的方法不更改保存

我正在通過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設置。 [facepalm]

+0

你可以發佈函數聲明嗎?看起來,如果你添加正確的屬性,它應該工作:http://stackoverflow.com/questions/4758575/how-can-i-access-session-in-a-webmethod'[的WebMethod(EnableSession =真)]' – ps2goat

+0

它可能是一個配置問題?也許與POST與GET的問題?當用戶登錄時,我們設置了一堆會話變量,並且它們保持得很好,但如果我在此處執行操作,則無法對會話進行更改。 –

+0

什麼版本。網你正在與,只是這樣我可以更準確地測試這個? – ps2goat

回答

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

+0

SessionState當前設置爲SQLServer模式,這是否與StateServer完成相同? –

+0

如果您已驗證會話持續到SQL Server,那麼是的,這與StateServer完成相同的事情。您可能還必須爲自定義對象實現自定義序列化。 閱讀本文的「out-pro-proc」會話以確保您的自定義對象將被正確序列化/反序列化:http://www.hanselman.com/blog/TroubleshootingExpiredASPNETSessionStateAndYourOptions.aspx –

1

如果您的會話沒有超時,最可能的原因是ASP.NET在您的webmethod請求和您的(aspx?)頁面調用之間生成了不同的sessionID。您可能在兩個Web方法調用之間有相同的會話可用(如果沒有超時並啓用了Cookie),但不能跨越頁面調用和web方法。

Cannot get session in webmethod in asp.net

+0

我可以獲取會話變量(例如用戶的姓名,電子郵件地址等),這些都是在應用程序的其他地方設置的,但是我在WebMethod中更改的任何內容都不會存在。 –

+0

getSessionTooling定義在哪裏?您沒有將httpcontext傳遞給該方法,它可能不會爲請求獲取正確的httpcontext。嘗試將上下文傳遞給方法調用。 – Vivek

+0

它在我的'ToolingModel'類中定義。我曾嘗試從WebMethod傳入會話,但我在會話中遇到了與保留更改不同的問題。 –