次の例に基づいて、セッション変数を保存および取得するセッション ヘルパーを実装しました: (セッション変数の使用を最小限に抑えようとしています )
私は MVC 4 を使用し、Visual Studio 2012 で .NET 4.5 をターゲットにしています。
セッターを実装しました。これは HttpContextBase (つまり、controller.HttpContext) を使用します。
public class HttpContextBaseSessionHelper : ISessionHelper
{
private readonly HttpContextBase _context;
public HttpContextBaseSessionHelper(HttpContextBase context)
{
_context = context;
}
public T Get<T>(string key)
{
object value = _context.Session[key];
return value == null ? default(T) : (T)value;
}
public void Set<T>(string key, T value)
{
_context.Session[key] = value;
}
}
この実装では、HttpContext (つまり、System.Web.HttpContext.Current) を使用します。
public class HttpContextSessionHelper : ISessionHelper
{
private readonly HttpContext _context;
public HttpContextSessionHelper(HttpContext context)
{
_context = context;
}
public T Get<T>(string key)
{
object value = _context.Session[key];
return value == null ? default(T) : (T)value;
}
public void Set<T>(string key, T value)
{
_context.Session[key] = value;
}
}
コントローラーでは、HttpContext プロパティの型は HttpContextBase (Controller.HttpContext) です。HttpContextBase に基づいて ISessionHelper を (Moq を使用して) モックできます。
次の 2 つのコントローラー アクションを使用して、実行中のアプリ (単体テストではなく) で、正しい値が設定および取得されているかどうかを確認します。
public ActionResult SessionSet()
{
_sessionHelper.Set<string>("TestKey", "TestValue");
ViewBag.SessionValue = (string)HttpContext.Session["TestKey"];
return View();
}
public ActionResult SessionGet()
{
HttpContext.Session["TestKey"] = "TestValue";
ViewBag.SessionValue = _sessionHelper.Get<string>("TestKey");
return View();
}
上記のアクションを使用すると、この実装は NullReference 例外をスローします。
_sessionHelper = new HttpContextBaseSessionHelper(HttpContext);
しかし、この実装は問題なく動作します:
_sessionHelper = new HttpContextSessionHelper(System.Web.HttpContext.Current);
私の質問は、なぜこれが起こるのですか? HttpContextBase を使用する実装と HttpContext を使用する実装は、Controller.HttpContext が HttpContextBase 型を返すことを確認して問題を引き起こすべきではありませんか?