我有一个中间件来记录 web api 请求。下面是 Startup.cs
中的 Configuration
方法。如果 app.UseMiddleware
在 app.UseMvc
之前出现,则不会调用任何 Web 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);
}
}
最佳答案
您必须始终在中间件中调用 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/