我有一個應用程式,來自許多不同作業站的許多人都在使用該應用程式。在這個應用程式中,當用戶登錄時,會話中存盤了各種用戶詳細資訊。這些詳細資訊首先存盤在 global.asax 檔案中:
Sub Begin(ByVal sender As Object, ByVal e As EventArgs) Handles Me.AcquireRequestState
(various code that gets user details)
HttpContext.Current.Session("ID") = UserID
End Sub
我創建了一個類檔案來更容易地參考會話變數,呼叫 Portal 類。它看起來像這樣(Portal.vb):
Public Class Portal
Public Class User
Public Shared ID As Integer = HttpContext.Current.Session("ID")
End Class
End Class
在我的應用程式中,比如說,默認頁面 (Default.aspx),我參考用戶 ID 來做各種事情:
Sub Page_Load() Handles Me.Load
Dim ID As Integer = Portal.User.ID
(Do stuff with the ID)
End Sub
發生的問題是,當有人當天第一次登錄時,在 Default.aspx 代碼中看到的 ID 是第一個用戶的 ID。但是當下一個人在完全不同的作業站上登錄時,在 Default.aspx 代碼中看到的 ID 仍然是第一個用戶的 ID。我已經確認分配給用戶的 ID 沒有問題。我知道 global.asax 檔案在會話中放置了正確的 ID。我已經通過檢查會話(“ID”)確認了這一點。
出于某種原因,在訪問類檔案 (Portal.vb) 中的會話時,所參考的會話始終是第一個人的會話。有誰知道這怎么可能?
uj5u.com熱心網友回復:
Public Shared ID As Integer = HttpContext.Current.Session("ID")
這將ID使用當前會話 ID 的值初始化變數一次。您的代碼永遠不會更新User類中的此值。所以你總是得到第一個用戶的會話 ID。
要修復它,請使其成為查詢并回傳當前會話 ID 的方法或屬性。
uj5u.com熱心網友回復:
在大多數情況下,我能夠弄清楚。
TLDR(太長,未讀)回答:我需要讓類屬性以我不熟悉的方式使用 Getter。
長答案:
所以在 Portal.vb 類檔案中,我首先有類“欄位”:
Public Shared ReadOnly UserID as Integer = HttpContext.Current.Session(“UserID”)
我選擇欄位而不是屬性是因為我希望這些類值不可編輯(只讀),并且不能使類屬性不可編輯(或者我認為)。換句話說,以下代碼是不允許的:
Public Shared Const Property UserID as Integer = HttpContext.Current.Session(“UserID”)
編譯器不允許您將屬性設為常量(Const),也不允許只讀(ReadOnly),說它不允許屬性的只讀自動實作。我認為,也許類欄位和類屬性之間存在問題,所以我嘗試將所有欄位轉換為屬性,省略“Const”位,只是為了看看它是否有效:
Public Shared Property UserID As Integer = HttpContext.Current.Session(“UserID”)
它沒有效果。
上面的“Omajid”建議類值被設定一次并且永遠不會被更新。這在某種程度上可以解釋這種行為。我不明白這到底是怎么回事,因為我認為每當參考類值時,與之相關的代碼都會執行,每次都從會話中提取值。所以我想也許 Getter/Setter 的作業方式有所不同。所以我嘗試使用 Getter/Setter 設定類屬性,因為我了解如何做到這一點:
Private _userid As Integer = HttpContext.Current.Session(“UserID”)
Public Property UserID() As Integer
Get
Return _userid
End Get
Set(value As Integer)
_userid = value
End Set
End Property
這再次沒有效果。而且,具有諷刺意味的是,Visual Studio 本身建議我應該使用“自動屬性”,這將整個代碼塊簡化為:
Public Property UserID() As Integer = HttpContext.Current.Session("UserID")
這沒有效果。這就是為什么我從來沒有真正設定過 Getter/Setter;在大多數情況下,它們似乎并不是必需的,因為在 VB 中有這種速記方式。
我的一個同事給我發了這篇文章:
如何從 ASP.NET 中的任何類訪問會話變數?
它有一個例子,其中有一個不同的 Getter 安排,這讓我覺得我可以做一些類似的事情。所以我設定類屬性是這樣的:
Public Shared ReadOnly Property UserID As Boolean
Get
Return HttpContext.Current.Session("UserID")
End Get
End Property
答對了。這成功了。它實作了我想要的兩件事:它更新了每個用戶的值,并且允許我將屬性設為只讀 (ReadOnly),因為沒有 Set 方法。
所以我在這里學到的是類欄位/屬性在構造時設定一次,而不是再次設定。并且為了在每次參考時更新類屬性,需要通過 Get 方法來完成。
Since the real reason behind this question is that I needed to get the user's details to update to their own and not reference someone else's when calling the Portal class, this is the solution. That said, one bit that still hasn’t been answered: How is it that class properties that are set in one user’s session are accessible by another user in another session? This, to me, seems like a huge security risk. But perhaps that’s only because I don’t understand the process.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/340287.html
