c# - 中间件中断了 web api 调用

标签 c# asp.net asp.net-web-api middleware

我有一个中间件来记录 web api 请求。下面是 Startup.cs 中的 Configuration 方法。如果 app.UseMiddlewareapp.UseMvc 之前出现,则不会调用任何 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);
 }

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

关于c# - 中间件中断了 web api 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58707890/

相关文章:

c# - 单个方法中有 2 个不同的代码,可能使用 Type

c# - 绑定(bind)到 BindingList 的 DataGridView 显示空行

c# - 统计一个主题的所有订阅

C#图像识别

c# - Asp net Core 获取用户Windows用户名

c# - .Net MVC4 重定向到操作未按预期工作

ASP.net MVC6 标记帮助程序生成无效标记?

jquery-mobile - JQuery Mobile + WebApi + PhoneGap

c# - 多个 Controller 端点之间的 Web Api 交互

c# - Controller Action 命名约定