中间件中断了网络 api 调用

Middleware breaks the web api calls

我有一个中间件来记录网络 api 请求。下面是 Startup.cs 里面的 Configuration 方法。如果 app.UseMiddlewareapp.UseMvc none 之前调用 Web api 调用但是,如果 app.UseMiddlewareapp.UseMvc 之后,中间件不会执行任何东西(即记录请求)。

我提供了下面的代码。知道为什么 app.UseMiddleware 会干扰 asp.UseMvc 吗?

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider services)
{
    // global cors policy
    app.UseCors(x => x
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader());


    app.UseHttpsRedirection();
    app.UseAuthentication();

    app.UseStaticFiles();
    app.UseSpaStaticFiles();

    app.UseMiddleware<ApiLoggingMiddleware>();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller}/{action=Index}/{id?}");
    });
}

中间件如下:

 public async Task Invoke(HttpContext httpContext, IApiLogService apiLogService)
 {
     try
     {
         _apiLogService = apiLogService;

         var request = httpContext.Request;
         if (request.Path.StartsWithSegments(new PathString("/api")))
         {
             var stopWatch = Stopwatch.StartNew();
             var requestTime = DateTime.UtcNow;
             var requestBodyContent = await ReadRequestBody(request);
             var originalBodyStream = httpContext.Response.Body;

             await SafeLog(requestTime,
                   stopWatch.ElapsedMilliseconds,
                   200,//response.StatusCode,
                   request.Method,
                   request.Path,
                   request.QueryString.ToString(),
                   requestBodyContent
                   );           
         }
         else
         {
             await _next(httpContext);
         }
     }
     catch (Exception ex)
     {
         await _next(httpContext);
     }
 }

您必须始终在中间件中调用 await _next(httpContext);,否则请求不会通过管道:

public async Task Invoke(HttpContext httpContext, IApiLogService apiLogService)
 {
     try
     {
         _apiLogService = apiLogService;

         var request = httpContext.Request;
         if (request.Path.StartsWithSegments(new PathString("/api")))
         {
             var stopWatch = Stopwatch.StartNew();
             var requestTime = DateTime.UtcNow;
             var requestBodyContent = await ReadRequestBody(request);
             var originalBodyStream = httpContext.Response.Body;

             await SafeLog(requestTime,
                   stopWatch.ElapsedMilliseconds,
                   200,//response.StatusCode,
                   request.Method,
                   request.Path,
                   request.QueryString.ToString(),
                   requestBodyContent
                   );           
         };
     }
     catch (Exception ex)
     {

     }
     await _next(httpContext);
 }

编辑(中间件的简单解释):
整个中间件的工作方式如下 - 当请求到达您的应用程序时,它会通过中间件管道,其中每个中间件都必须调用下一个中间件才能最终将请求发送到您的控制器。当您调用 await _next(httpContext); 时,您基本上是在调用管道中下一个中间件的 Invoke 方法。如果您不调用 await _next(httpContext); 您将停止请求并且它不会到达您的控制器。需要注意的一件事是,当 await _next(httpContext); returns 时,您的控制器已经处理了请求。