私は、ユーザーが特定の要求を行うWebサイト内の複数のWebページを参照できるようにするWebアプリケーションを作成しています。ユーザーが入力するすべての情報は、私が作成したオブジェクトに保存されます。問題は、このオブジェクトにWebサイトの任意の部分からアクセスする必要があり、これを実現するための最良の方法がわからないことです。1つの解決策はセッション変数を使用することですが、asp.netMVCでそれらを使用する方法がわかりません。そして、どこでセッション変数を宣言しますか?他に方法はありますか?
10 に答える
物事が本当にセッション状態に属しているかどうかを考えてみたくなると思います。これは私が時々やっていることに気づき、全体に対して強く型付けされた良いアプローチですが、セッションのコンテキストに物事を置くときは注意する必要があります。あるユーザーのものであるという理由だけで、すべてがそこにあるべきではありません。
global.asaxでOnSessionStartイベントをフックします
void OnSessionStart(...)
{
HttpContext.Current.Session.Add("__MySessionObject", new MySessionObject());
}
HttpContext.Currentプロパティ!= nullであるコード内のどこからでも、そのオブジェクトを取得できます。私はこれを拡張メソッドで行います。
public static MySessionObject GetMySessionObject(this HttpContext current)
{
return current != null ? (MySessionObject)current.Session["__MySessionObject"] : null;
}
このようにして、コードで行うことができます
void OnLoad(...)
{
var sessionObj = HttpContext.Current.GetMySessionObject();
// do something with 'sessionObj'
}
ここでの答えは正しいですが、ASP.NET MVC 3 アプリに実装するのに苦労しました。コントローラーで Session オブジェクトにアクセスしたかったのですが、「インスタンスがオブジェクトのインスタンスに設定されていません」というエラーが発生し続ける理由がわかりませんでした。私が気づいたのは、コントローラーで次のようにしてセッションにアクセスしようとしたときに、そのエラーが発生し続けたことです。これは、this.HttpContext が Controller オブジェクトの一部であるためです。
this.Session["blah"]
// or
this.HttpContext.Session["blah"]
ただし、私が欲しかったのは、System.Web 名前空間の一部である HttpContext でした。これは、上記の回答が Global.asax.cs で使用することを示唆しているためです。したがって、次のことを明示的に行う必要がありました。
System.Web.HttpContext.Current.Session["blah"]
ここでMO以外のことをしたかどうかはわかりませんが、誰かの役に立てば幸いです!
場所について「HTTPContext.Current.Session」を見るのは嫌いなので、シングルトン パターンを使用してセッション変数にアクセスします。これにより、強く型付けされたデータのバッグに簡単にアクセスできます。
[Serializable]
public sealed class SessionSingleton
{
#region Singleton
private const string SESSION_SINGLETON_NAME = "Singleton_502E69E5-668B-E011-951F-00155DF26207";
private SessionSingleton()
{
}
public static SessionSingleton Current
{
get
{
if ( HttpContext.Current.Session[SESSION_SINGLETON_NAME] == null )
{
HttpContext.Current.Session[SESSION_SINGLETON_NAME] = new SessionSingleton();
}
return HttpContext.Current.Session[SESSION_SINGLETON_NAME] as SessionSingleton;
}
}
#endregion
public string SessionVariable { get; set; }
public string SessionVariable2 { get; set; }
// ...
その後、どこからでもデータにアクセスできます。
SessionSingleton.Current.SessionVariable = "Hello, World!";
asp.net mvcを使用している場合、セッションにアクセスする簡単な方法は次のとおりです。
コントローラーから:
{Controller}.ControllerContext.HttpContext.Session["{name}"]
ビューから:
<%=Session["{name}"] %>
これは、セッション変数にアクセスするための最良の方法ではありませんが、直接的なルートです。したがって、注意して(できればラピッドプロトタイピング中に)使用し、適切になったときにWrapper/ContainerとOnSessionStartを使用してください。
HTH
それには3つの方法があります。
直接アクセスできます
HttpContext.Current.Session
あなたはモックすることができます
HttpContextBase
の拡張メソッドを作成する
HttpContextBase
私は 3 番目の方法を好みます。このリンクは参考になります。
BaseController での HttpContext セッション メソッドの取得/設定と、Get/Set メソッドを作成するための HttpContextBase のモッキング
asp.net mvc についてはわかりませんが、これは通常の .net Web サイトで行うべきことです。asp.net mvc でも機能するはずです。
YourSessionClass obj=Session["key"] as YourSessionClass;
if(obj==null){
obj=new YourSessionClass();
Session["key"]=obj;
}
簡単にアクセスできるように、これをメソッド内に配置します。HTH
セッションにアクセスする私の方法は、さまざまなフィールド名とその型をカプセル化するヘルパー クラスを作成することです。この例が役立つことを願っています:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.SessionState;
namespace dmkp
{
/// <summary>
/// Encapsulates the session state
/// </summary>
public sealed class LoginInfo
{
private HttpSessionState _session;
public LoginInfo(HttpSessionState session)
{
this._session = session;
}
public string Username
{
get { return (this._session["Username"] ?? string.Empty).ToString(); }
set { this._session["Username"] = value; }
}
public string FullName
{
get { return (this._session["FullName"] ?? string.Empty).ToString(); }
set { this._session["FullName"] = value; }
}
public int ID
{
get { return Convert.ToInt32((this._session["UID"] ?? -1)); }
set { this._session["UID"] = value; }
}
public UserAccess AccessLevel
{
get { return (UserAccess)(this._session["AccessLevel"]); }
set { this._session["AccessLevel"] = value; }
}
}
}
みんなからの素晴らしい答えですが、常にセッションに頼らないように注意してください。これは迅速かつ簡単に実行でき、もちろん機能しますが、すべての状況で優れているわけではありません。
たとえば、ホスティングでセッションの使用が許可されていないシナリオに遭遇した場合、または Web ファームにいる場合、または共有 SharePoint アプリケーションの例の場合です。
別のソリューションが必要な場合は、Castle WindsorなどのIOC コンテナーを使用して、プロバイダー クラスをラッパーとして作成し、要件に応じて要求ごとまたはセッションのライフスタイルを使用してクラスの 1 つのインスタンスを保持することを検討できます。
IOC は、毎回同じインスタンスが返されるようにします。
はい、もっと複雑です。単純な解決策が必要な場合は、セッションを使用してください。
興味のある実装例を以下に示します。
このメソッドを使用すると、次の行に沿ってプロバイダー クラスを作成できます。
public class CustomClassProvider : ICustomClassProvider
{
public CustomClassProvider(CustomClass customClass)
{
CustomClass = customClass;
}
public string CustomClass { get; private set; }
}
そして、次のように登録します。
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ICustomClassProvider>().UsingFactoryMethod(
() => new CustomClassProvider(new CustomClass())).LifestylePerWebRequest());
}