2017-06-16 139 views
0

我們在IIS中託管的ASP.NET Web API 2項目中使用Owin中間件。ASP.NET Web API HttpContext響應在IOwinContext響應之前發回

我目前遇到了一個奇怪的現象,即IOwinContext.Response.Body沒有被寫入,實際上,即使在喚醒Next.Invoke()後在中間件中設置了中斷點, ,即使我還沒有繼續,響應已經被髮送回服務器。

當我查看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); 
    } 
} 

我敢肯定我的中間件搞砸,但反應已經消失了它會回到我的第一個中間件(Middleware3)後等待Next.Invoke()

任何之前洞察力或思想挑釁將不勝感激。另外,如果這些信息不夠,請告訴我。

回答

0

因此,正如在我上面的帖子中,我想,問題是HttpResponse在IOwinResponse之前被髮回。當你使用它app.Map()分支中間件

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

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

:事實證明,我完全忽略了映射部分。所以,如果路徑匹配「/ api」,它會分支。但是,它還在使用app.UseWebApi()組件,所以這就是爲什麼我有兩個不同的響應,以及爲什麼我期望的響應沒有寫入Middleware3組件的IOwinContext。 我固定它通過去除app.MapWhen()方法,從這個改變它:

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 
}); 

這樣:

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

newApp.Use<Middleware3>(); 

並把這段代碼在中間件組件Middleware1Middleware2的開始,Middleware3

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.Map的擴展方法,這裏有一些文檔https://msdn.microsoft.com/en-us/library/owin.mapwhenextensions.mapwhen(v=vs.113).aspx