【问题标题】:asp.net Core Add Response Headers in Middleware after UseRoutingasp.net Core 在 UseRouting 之后在中间件中添加响应头
【发布时间】:2021-12-12 20:38:54
【问题描述】:

我正在尝试通过中间件添加服务器端延迟标头。我看过几个有类似问题的 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();
}

我必须在UseRoutingUseEndpoints 之后注册MyHeaderMiddleware,因为它还需要端点数据。

然后在扩展方法类中,我有以下内容。

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 响应中。

【问题讨论】:

  • 可能有一些东西会影响你的结果,我很惊讶如果响应头没有出现,如果它在UseRouting 之后注册并自己进行了测试并且它按预期工作(我只是复制您的代码并使用实现的类中间件,而不是内联中间件样式),您能否展示metricsSetup 是如何实现的?
  • 那里的代码很多,但我会把主要部分粘贴到示例中。

标签: asp.net asp.net-core middleware


【解决方案1】:

我更改了一些步骤的顺序,最终使它起作用。主要的变化就是这个。

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(),即使端点在启动时位于此中间件之后,也可以使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 2014-07-30
    • 2016-03-09
    • 2015-06-12
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    相关资源
    最近更新 更多