2017-04-02 17 views
1

私はASP.NET Core API用のいくつかのロギングサービスを作成しています。
私はミドルウェアを書きました。これは、呼び出されているすべてのアクションをログに記録します(クロスカッティングの懸念、論理的に思われます)。コントローラの外部でHttpContextを使用する - 悪い習慣ですか?

私が記録したかったことの1つは、ユーザーのIP(たとえば)です。 私はそのデータを取得することが考えられる唯一の方法はHttpContext.Connectionです。
期待通りに機能しました。

But lately I've been readingもう少しで、私はコントローラー外のHttpContextにアクセスすることは悪い習慣と考えられることを理解しています。 模擬や模倣が非常に難しいため、コードをテストすることはできません。
また、このコードは他の.NETアプリケーションに移植することもできず、ASP.NETアプリケーションのコンテキストで使用する必要があります。

私の質問は、コントローラの外でHttpContextを使用することは本当に悪いことですか?
もしそうなら、代替手段は何ですか?

HttpContext ASP.NET内で使用されるコンポーネント(TOPレベルのコントローラやミドルウェアなど)が正当なものであるかどうかをご確認ください。

ありがとうございました。

+1

です。あなたのドメイン層(=ドメインサービス)内でそれを参照する場合、ドメインはインフラストラクチャ(db、webservice、asp.net、wpf、uwpなどのホストなど)に依存する必要がないため、間違いなく最悪のことの1つです。 )。アプリケーション層(=アプリケーションサービス)で使用されている場合は問題ありません。違いは、アプリケーションレベルはアプリケーションに結びついており、ほとんどポータブルではない(つまり、httpcontext情報にアクセスすると、httpコンテキストがないためWPFでは動作しません) – Tseng

+0

@Tseng、そうだと思います。だから、トップレベルのコントローラーやミドルウェアで使用するのがOKかどうかを尋ねたのは、ASP.Netのスコープ内にあるすべてのコードを意味します。 – DotnetProg

答えて

3

コントローラ外のASP.NETコアでHttpContextクラスのインスタンスを使用するのはまったく問題ありません。特に、現在の要求を表すHttpContextのインスタンスがなければ、ミドルウェアを書くことは役に立たないでしょう。

主な違いは、スタティックアクセサHttpContext.CurrentのようにASP.NET System.Webのように使用しないでください。あなたの既存のコードの多くがこれに依存している場合、あなたの参照されたブログ投稿は、ASP.NET Coreでこれを模倣する方法に関するものです。 ASP.NETのコア用語では、コンテキストのインスタンスがミドルウェアのInvokeメソッドに渡されるか、または依存性注入を使用してIHttpContextAccessorオブジェクトにアクセスできます。

ASP.NET Core Docsのこのサンプルをご覧ください。 HttpContextはパラメータ名contextとして注入されるため、HttpContext.Currentのような静的アクセサに依存する必要はありません。特にこれはテストするのが簡単です。単体テストでHttpContextのインスタンスを作成し、Invokeメソッドに渡すことができるからです。

public class RequestCultureMiddleware 
{ 
    private readonly RequestDelegate _next; 

    public RequestCultureMiddleware(RequestDelegate next) 
    { 
     _next = next; 
    } 

    public Task Invoke(HttpContext context) 
    { 
     var cultureQuery = context.Request.Query["culture"]; 
     if (!string.IsNullOrWhiteSpace(cultureQuery)) 
     { 
      var culture = new CultureInfo(cultureQuery); 

      CultureInfo.CurrentCulture = culture; 
      CultureInfo.CurrentUICulture = culture; 

     } 

     // Call the next delegate/middleware in the pipeline 
     return this._next(context); 
    } 
} 
+0

私が気付いたように、 'HttpContext'パラメーターがミドルウェアに渡され、それで私はクライアントのリモートIPアドレスを取得できました。私は、 'HttpContext'のインスタンスと静的な' HttpContext.Current'インスタンスの使用の微妙な違いに気づいていませんでした。だから私を安心させてくれてありがとう。 – DotnetProg

関連する問題