2009-05-20 26 views
80

なぜコントローラはコンストラクタでセッションがnullですか? Actionメソッドからアクセスできます。おそらく、MVC Routingフレームワークはコントローラの新規作成を担当するため、その時点でSessionをインスタンス化していないだけです。ASP.Net MVCコントローラのコンストラクタのセッションnull

これは設計上のものであれば誰でも知っていますか?

[Iは、レイジーローディングパターンを使用して問題を回避するために管理している。]

答えて

68

Andreiが正しい - ASP.NET MVCフレームワークで実行すると、HttpContext(したがってHttpContext.Session)はコントローラクラスが想定どおりに構築されていても設定されていないので、注入された ")を後でControllerBuilderクラスで作成します。ライフサイクルをよりよく理解したい場合は、ASP.NET MVCフレームワーク(ソースが利用可能)をプルダウンするか、次を参照してください:this page

セッションにアクセスする必要がある場合は、 "OnActionExecuting"メソッドを呼び出して、そこにアクセスしてください。

しかしAndreiが示唆しているように、あなたのコードがセッションに依存している場合、単体テストを書くのは難しい可能性があります。したがって、おそらくセッションをヘルパークラスにラップすることができます。単体テストで動作している場合にはウェブ以外のバージョンではないため、コントローラをウェブから切り離す必要があります。ここでは他の回答に加えて

+1

これはHttpContextについての適切なステートメントであるかどうかわかりません。 実際には全体の流れの開始時に正しく構築されました。詳細なフローについては、http://www.beletsky.net/2011/06/inside-aspnet-mvc-route-to-mvchanlder.html を読むか、リフレクタを使用して、httpContextがインスタンス化されたときに自分自身を見つけることができます - httpruntime.csの1556行目。 –

+0

@AlexeyShcherbak既に構築されている可能性があります.OPは、MVCコントローラのSessionプロパティにOPが設定されているかどうかを示します。つまり、public HttpSessionStateBase Session {get; } on System.Web.Mvc.Controllerこれは別のものです。 – MemeDeveloper

10

をセッションがライフサイクルの後半に注入されます。とにかく、コンストラクタでセッションが必要なのはなぜですか?あなたがTDDのためにそれを必要とするなら、あなたはモック可能なオブジェクトにセッションを包むべきです。

+1

はアンドレイRineaに追加するには、これは彼が言及した手法の具体例であります:http://iridescence.no/post/Using-Uni​​t-Tests-to-Uncover-Design-Flaws.aspx – murki

+4

私は以前に保存されたセッション情報にアクセスできるように、私のコンストラクタでセッションにアクセスしたいと思います。はい、私はOnActionExecutingメソッドをオーバーライドできますが、これは確かに洗練されたソリューションではありません。 –

+0

@ChrisArnold、私の答えを見てください。 –

50

Controller.Sessionがコンストラクタに移入されていない間、あなたはまだを通じてセッションにアクセスすることができます。これは潜在的にあなたのコントローラのテスト容易性を減少させることを、標準的な警告と

System.Web.HttpContext.Current.Session

+3

これらの2つのセッションプロパティのそれぞれのタイプは異なります。これは、セッションステート自体への参照を保持する場合に重要です。 – BrianCooksey

+0

@BrianCooksey何が違うのですか? – MichaelMao

+1

Controller.SessionはタイプSystem.Web.HttpSessionStateBaseである(https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.session(v=vs.118).aspxを参照)が、 System.Web.HttpContext.Current.Sessionは、System.Web.SessionState.HttpSessionState型です(https://msdn.microsoft.com/en-us/library/system.web.httpcontext.session(v=vs.110)を参照)。 ).aspx) – BrianCooksey

6

Initializeメソッドをオーバーライドしてセッションを設定できます。

protected override void Initialize(RequestContext requestContext) 
2

はあなたのIoCコンテナを使用している場合は、注入しSessionオブジェクトではなくHttpSessionStateBaseを使用してみてください:

private static Container defaultContainer() 
{ 
    return new Container(ioc => 
    { 
        // session manager setup 
        ioc.For<HttpSessionStateBase>() 
           .Use(ctx => new HttpSessionStateWrapper(HttpContext.Current.Session)); 
    }); 
} 
関連する問題