Middleware прерывает вызовы веб-API - PullRequest
2 голосов
/ 05 ноября 2019

У меня есть промежуточное программное обеспечение для регистрации веб-запросов API. Ниже приведен метод Configuration внутри Startup.cs. Если app.UseMiddleware предшествует app.UseMvc, то ни один из вызовов веб-API не вызывается. Однако, если app.UseMiddleware идет после app.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);
     }
 }

1 Ответ

3 голосов
/ 05 ноября 2019

Вы должны всегда вызывать 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);, ваш контроллер уже обработал запрос.

...