2016-04-19 8 views
3

私のミドルウェアクラスは異なるクラスライブラリプロジェクトにあり、コントローラは異なるプロジェクトにあります。特定の条件がミドルウェアからカスタムコントローラ/アクションメソッドにリダイレクトされない場合、私がやろうとしていること。ミドルウェアからコントローラのアクションメソッドを呼び出す

しかし、私はResponse.Redirectメソッドでそれを行うことはできません。

ミドルウェアクラスでこれを行うにはどうすればよいですか?

この点に関するお役に立ちましたか?

Rohit

+1

条件は何ですか?それは認証/承認ですか、それとも何か他のものですか?認証されている場合は、おそらく '401'や' 403'(認証や認可が失敗したかどうかに依存します)を返すことになります。もしそうであれば、まずミドルウェアでやりたいとは思わないでしょう。より具体的になりますか? –

+0

@ TomasLyckenはい、特定のクライアント/テナントが見つからない場合は、認証/承認に関連していません。そのため、一部のコントローラのアクションメソッドにリダイレクトしてエラーメッセージを表示します。 httpcontextからクライアント名を取得するにはロジックがミドルウェア – Rohit

答えて

5

あなたは間違った理由でミドルウェアを使用しているようです。

ミドルウェアに応答ストリーム(単にNext()に転送するのではなく)に書き込むか、またはミドルウェアではなくあなたのMVCアプリケーションにグローバルに登録されたIActionFilter。私はコメント欄で上記の助言のための理論的根拠を説明してきましたが、私はそれが実際の答えに持ち上げるために十分な重要なことだと思う


ミドルウェア・パイプラインでは、各コンポーネントのようになりたいです可能な限り独立しています。各成分が同じフォーマットを有し、10から他のミドルウェア・その前の成分、またはnoneすべて

であるかどうかを、

  • に入力され、出力:物事のカップルはOWINにおけるこの緩い結合を可能着信要求を

    1. 読む(および変更):

    2. 大会は、パイプラインの各部分がこの順に、3つのうちの一つ以上の操作を行うことができるということです。

    3. 要求を完全に処理するか、次のコンポーネントに処理を転送するかを決定します。

    4. 応答ストリームに書き込みます。

これらの規則に付着し、それは、作曲分解し、再利用可能なミドルウェア・コンポーネントからのパイプラインを再構成することは非常に容易になります。 (要求ロギングをしたいのですが、パイプの始めにミドルウェアコンポーネントを接続するだけです。ボード全体の一般的な認証ロジックを必要としますか?パイプの認証ステージにコンポーネントを追加します。コンポーネントを再利用してください。等号、広告の無限...)これは非常にうまくいきます。これは、コンポーネントが境界内にとどまり、Webサーバー自体が理解できる。

ASP.NET WebAPIは別の獣だと思われるかもしれませんが、実際はリクエストを処理するように常に構成されている別のOWINコンポーネントであり、次のコンポーネントに転送しない(したがって、パイプラインでWebApiの後にコンポーネントを登録する...)。

あなたがしようとしていることは、そこにある2番目の点の契約を破っています。次のコンポーネントに要求の処理方法を伝えたいと思います。 しかしそれはあなた次第ではありません。次の要素までです。

+0

で書かれていますか?404とIActionFilterの少しの例を教えてください。ありがとう! – Rohit

+0

レスポンスへの書き込みについては、 [this Q/A](http://stackoverflow.com/questions/32532058/how-do-i-ask-owin-katana-to-write-headers-to-the-output-stream) 'IActionFilter'の例については、[here](https://damienbod.com/2014/01/04/web-api-2-using-actionfilterattribute-overrideactionfiltersattribute-and-ioc-injection/)をご覧ください。 –

+0

あなたは理由を教えてください。彼のユースケースはミドルウェアには不適切です。 –

5

ここにはリクエストとリダイレクトを調べるミドルウェアがあります。これは、インラインミドルウェアまたはミドルウェアクラスのいずれかで動作します。

public void Configure(IApplicationBuilder app) 
{ 
    // use inline middleware 
    app.Use(async (context, next) => 
    { 
     // if specific condition does not meet 
     if (context.Request.Path.ToString().Equals("/foo")) 
     { 
      context.Response.Redirect("path/to/controller/action"); 
     } 
     else 
     { 
      await next.Invoke(); 
     } 
    }); 

    // or use a middleware class 
    app.UseMiddleware<RedirectMiddleware>(); 

    app.UseMvc(); 
} 

次はミドルウェアクラスです。

public class RedirectMiddleware 
{ 
    private readonly RequestDelegate _next; 

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

    public async Task Invoke(HttpContext context) 
    { 
     // if specific condition does not meet 
     if (context.Request.Path.ToString().Equals("/bar")) 
     { 
      context.Response.Redirect("path/to/controller/action"); 
     } 
     else 
     { 
      await _next.Invoke(context); 
     } 
    } 
} 

詳細については、Docs » Fundamentals » Middlewareを参照してください。

+1

StartupクラスのConfigureメソッドを提供しているようですか?ミドルウェアからエラーが発生した場合、どのように返すことができますか? – Rohit

+0

'app.Use'はミドルウェアです。私はそれをやる別の方法を追加しました。 –

+1

@ShaunLatin助けてくれてありがとう!その作業! – Rohit