これは WebProfile を取得する適切な方法ですか?
-
02-07-2019 - |
質問
戻るボタンを使用して Web ページに戻ると、別人として戻ってくると報告しているユーザーがいます。別のユーザー プロファイルにアクセスしているようです。
コードの重要な部分は次のとおりです。
//here's the code on the web page
public static WebProfile p = null;
protected void Page_Load(object sender, EventArgs e)
{
p = ProfileController.GetWebProfile();
if (!this.IsPostBack)
{
PopulateForm();
}
}
//here's the code in the "ProfileController" (probably misnamed)
public static WebProfile GetWebProfile()
{
//get shopperID from cookie
string mscsShopperID = GetShopperID();
string userName = new tpw.Shopper(Shopper.Columns.ShopperId, mscsShopperID).Email;
p = WebProfile.GetProfile(userName);
return p;
}
私は静的メソッドを使用しています。 static WebProfile
プロファイルオブジェクトを使用する必要があるため、 static WebMethod
(アヤックス pageMethod
).
- これにより、プロファイル オブジェクトがさまざまなユーザーによって「共有」される可能性がありますか?
- 静的メソッドと静的オブジェクトを正しく使用していませんか?
私が変わった理由 WebProfile
に反対する static
オブジェクトは、内のプロファイルオブジェクトにアクセスする必要があるためでした。 [WebMethod]
(ページ上のJavaScriptから呼び出されます)。
- 内のプロファイルオブジェクトにアクセスする方法はありますか?
[WebMethod]
? - そうでない場合、どのような選択肢がありますか?
解決
静的オブジェクトはアプリケーションのすべてのインスタンスで共有されるため、静的オブジェクトの値を変更すると、その変更はそのオブジェクトにアクセスするアプリケーションのすべてのインスタンスに反映されます。したがって、Web プロファイルが別のスレッドによって再割り当てされた場合 (つまり、ページにアクセスする 2 番目のユーザーなど)現在のユーザーに設定するまでの間に、期待とは異なる情報が含まれることになります。
これを回避するには、コードは次のようになります。
public WebProfile p = null;
protected void Page_Load(object sender, EventArgs e)
{
p = ProfileController.GetWebProfile();
if (!this.IsPostBack)
{
PopulateForm();
}
}
public static WebProfile GetWebProfile()
{
//get shopperID from cookie
string mscsShopperID = GetShopperID();
string userName = new tpw.Shopper(Shopper.Columns.ShopperId, mscsShopperID).Email;
return WebProfile.GetProfile(userName);
}
静的オブジェクトは設定されていないため、戻り値は呼び出しメソッド内の Web プロファイル クラスの非静的インスタンスに割り当てられる必要があることに注意してください。
もう 1 つのオプションは、静的変数が使用されている間ずっと静的変数をロックすることです。ただし、現在のロック スレッドが完了するまでロックはリソースに対する他のリクエストをブロックするため、パフォーマンスが大幅に低下します。ウェブアプリ。
他のヒント
@ゲリ
ユーザーのプロファイルが頻繁に変更されない場合は、現在のセッション状態にプロファイルを保存するオプションがあります。これにより、メモリのオーバーヘッドが発生しますが、プロファイルのサイズと同時ユーザーの数によっては、問題にならない可能性があります。次のようなことを行うとします。
public WebProfile p = null;
private readonly string Profile_Key = "CurrentUserProfile"; //Store this in a config or suchlike
protected void Page_Load(object sender, EventArgs e)
{
p = GetProfile();
if (!this.IsPostBack)
{
PopulateForm();
}
}
public static WebProfile GetWebProfile() {} // Unchanged
private WebProfile GetProfile()
{
if (Session[Profile_Key] == null)
{
WebProfile wp = ProfileController.GetWebProfile();
Session.Add(Profile_Key, wp);
}
else
return (WebProfile)Session[Profile_Key];
}
[WebMethod]
public MyWebMethod()
{
WebProfile wp = GetProfile();
// Do what you need to do with the profile here
}
これにより、必要に応じてプロファイルの状態がセッションから取得され、静的変数の必要性が回避されます。