asp.net - asp.net Core 在 UseRouting 之后在中间件中添加响应头
问题描述
我正在尝试通过中间件添加服务器端延迟标头。我看过几个有类似问题的 SO 帖子,但他们的解决方案对我不起作用。这是我的Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory factory)
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
app.MyHeaderMiddleware();
}
我必须在MyHeaderMiddleware
之后注册UseRouting
,UseEndpoints
因为它还需要端点数据。
然后在扩展方法类中,我有以下内容。
public static void MyHeaderMiddleware(this IApplicationBuilder app)
{
app.MyHeaderMiddleware((context, logger) =>
{
var actionDescriptor = endpoint.Metadata.GetMetadata<ControllerActionDescriptor>();
int status = context.Response.StatusCode;
if (context.Request.Host != null)
{
logger.PutProperty("Host", context.Request.Host.Value);
}
if (context.Request?.HttpContext?.Connection?.RemoteIpAddress != null)
{
logger.PutProperty("SourceIp", context.Request.HttpContext.Connection.RemoteIpAddress.ToString());
}
if (context.Request.Headers.TryGetValue("X-Forwarded-For", out StringValues value) && !String.IsNullOrEmpty(value) && value.Count > 0)
{
logger.PutProperty("X-Forwarded-For", value.ToArray());
}
return Task.CompletedTask;
});
}
public static void MyHeaderMiddleware(this IApplicationBuilder app, Func<HttpContext, IMetricsLogger, Task> metricsSetup)
{
app.Use(async (context, next) =>
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
var logger = context.RequestServices.GetRequiredService<IMetricsLogger>();
await metricsSetup(context, logger);
context.Response.OnStarting(() =>
{
stopWatch.Stop();
context.Response.Headers.Add("X-Server-Side-Latency", stopWatch.ElapsedMilliseconds.ToString());
return Task.CompletedTask;
});
await next();
});
}
如果我在之前注册了我的中间件UseRouting
,则会按预期添加标头,但如果它在之后,它会执行,但在响应中看不到标头。我需要设置我的指标记录器作为其中的一部分,因为我既记录了每个 API 调用的服务器端延迟,也将其放入 http 响应中。
解决方案
我改变了一些步骤的顺序,最终使它起作用。主要的变化是这样的。
await next(); // this will make the endpoints available in the logger setup
await metricsSetup(context, logger);
在较小程度上,这:
app.UseRouting();
app.UseEmfMiddleware();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
通过在设置指标记录器之前调用next()
,端点可用,即使它们在启动时位于此中间件之后。
推荐阅读
- pycharm - 输入 Pycharm 时如何禁用大的弹出窗口?
- google-maps - Google Maps API,标记 onClick 侦听器未按预期工作
- cassandra - Cassandra HeapDumpOnOutOfMemoryError
- python - 如何给从 0 开始的唯一整数 id 到随机给定数字?
- testing - 在 testcafe 的相同测试执行期间,如何使用与 Json 中写入的相同值
- r - R函数ifelse仅返回最后一行的评估
- terminal - PyCharm 终端:目录的奇怪背景颜色
- c# - 无法在 Windows 启动 Wpf 时打开数据库
- intellij-idea - 我试图进行突变测试。在 Intellij 的想法中,我使用了 ptest。但是我收到一条错误消息,提示无法创建 HTML 文件
- excel - 不同单元格中每个循环值的输出