2017-06-16 20 views
0

IISでホストされているASP.NET Web API 2プロジェクトでOwinミドルウェアを使用しています。ASP.NET Web API HttpContext IOwinContext応答の前に応答が返される

IOwinContext.Response.Bodyが書き込まれていない奇妙な現象が発生しています。実際には、起動後にミドルウェアにブレークポイントが設定されていても、ヒットします、私がまだ続行していなくても、応答はすでにサーバーに送り返されています。

私はIOwinContextの応答本文を見ると空です。しかし、私はHttpContext.Response.Filterから応答を得ることができます。私がHttpContextを使用してブレークポイントをヒットすると、私が続行するまで応答は返されません。以下は、Startup.csクラスで使用されている現在のコンフィグレーションメソッドです。

public async void Configuration(IAppBuilder app) 
{ 
    try 
    { 
     // Global Config 
     var config = GlobalConfiguration.Configuration; 

     // configure dependency injection 
     UnityConfig.RegisterComponents(); 

     // configure log for net 
     log4net.Config.XmlConfigurator.Configure(); 

     // turn around all requests right here 
     app.Use(async (context, next) => 
     { 
      if (context.Request.Path.ToString() == "/") 
      { 
       string text = "UP"; 
       context.Response.StatusCode = 200; 
       context.Response.ReasonPhrase = text; 
       await context.Response.WriteAsync(text); 
       return; 
      } 

      await next.Invoke(); 
     }); 

     // Handle exceptions in the OWIN layer here 
     app.UseUncaughtExceptionHandler(); 

     // add cors headers 
     app.Use(async (context, next) => { }); 

     // some UI stuff 
     app.Use(async (context, next) => { }); 

     // Log Request Metrics 
     app.UseLogRequestMetrics(); 

     // Evaluate Partner Key 
     app.MapWhen(context => Regex.IsMatch(context.Request.Uri.PathAndQuery.ToLower(), @"/api"), newApp => 
     { 
#if !DEBUG 
      newApp.Use<Middleware1>(); 
#endif 
      newApp.Use<Middleware2>(); 

      newApp.Use<Middleware3>(); // On the response path back, the IOwinResponse body is already empty 
     }); 

     WebApiConfig.Register(config); 

     app.UseWebApi(config); // It seems like I'm losing the response in here, but I don't really know 

     config.EnsureInitialized(); 

     // Configure object mapping 
     AutoMapperConfig.Configure(); 
    } 
    catch (Exception ex) 
    { 
     await LogForNetErrorLogger.LogError(ex); 
    } 
} 

私は私のミドルウェアが台無しにされてかなり確信しているが、それはのawait Next.Invoke(後に戻って私のミドルウェア(Middleware3)の最初に到達する前に応答がすでになくなっている)

どれでも洞察力や思考力が評価されるでしょう。また、これで十分でない場合は、私に知らせてください。

答えて

0

上記の私の記事のように、IOwinResponseが発生する前にHttpResponseが返送されていたと私は考えていました。結局のところ、私は完全にマッピング部を見落とし:

app.MapWhen(context => Regex.IsMatch(context.Request.Uri.PathAndQuery.ToLower(), @"/api"), newApp => 
{ 
#if !DEBUG 
    newApp.Use<Middleware1>(); 
#endif 
    newApp.Use<Middleware2>(); 

    newApp.Use<Middleware3>(); 
}); 

あなたはapp.Map()その枝のミドルウェアを使用した場合。したがって、パスが "/ api"と一致する場合は、分岐します。しかし、まだapp.UseWebApi()コンポーネントを使用していたので、2つの異なる応答があり、なぜ私が期待していた応答がMiddleware3コンポーネントのIOwinContextに書き込まれなかったのかが分かりました。 、Middleware3

#if !DEBUG 
newApp.Use<Middleware1>(); 
#endif 
newApp.Use<Middleware2>(); 

newApp.Use<Middleware3>(); 

及びミドルウェア・コンポーネントMiddleware1Middleware2の開始時にコードのこの部分を置く:

app.MapWhen(context => Regex.IsMatch(context.Request.Uri.PathAndQuery.ToLower(), @"/site"), newApp => 
{ 
#if !DEBUG 
    newApp.Use<Middleware1>(); 
#endif 
    newApp.Use<Middleware2>(); 

    newApp.Use<Middleware3>(); // On the response path back, the IOwinResponse body is already empty 
}); 

これに: Iは、app.MapWhen()メソッドを除去することによってそれを修正このからそれを変更します:

public override async Task Invoke(IOwinContext context) 
{ 
    if (!context.Request.Path.ToString().StartsWith("/api/")) 
    { 
     await Next.Invoke(context); 

     return; 
    } 

    // stuff I want to run if the above doesn't match 
    await Next.Invoke(context); 

    ... 
} 

少なくとも、修正は簡単でしたそれを見つけるために週。拡張メソッドIAppBuilder.MapWhenを読みたい場合は、https://msdn.microsoft.com/en-us/library/owin.mapwhenextensions.mapwhen(v=vs.113).aspxというドキュメントがあります。

関連する問題