如何将自定义标头添加到ASP.NET Core Web API响应

JDa*_*awg 42 c# asp.net-core-webapi

我正在将我的API从Web API 2移植到ASP.NET Core Web API.我曾经能够以下列方式添加自定义标头:

  HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
  response.Headers.Add("X-Total-Count", count.ToString());
  return ResponseMessage(response);
Run Code Online (Sandbox Code Playgroud)

如何在ASP.NET Core Web API中添加自定义标头?

Tim*_*ria 56

您可以HttpContext从传入的Http中获取Request插件,并Response在调用return之前将自己的自定义标头添加到对象.

如果您希望自定义页眉坚持和跨多个控制器的所有API请求添加,则应考虑制定Middleware,这是否对你的组件,然后在HTTP请求管道将其添加Startup.cs

public IActionResult SendResponse()
{
    Response.Headers.Add("X-Total-Count", "20");

    return Ok();
}    
Run Code Online (Sandbox Code Playgroud)


Dmi*_*lov 34

有一个简单GET操作的示例,它返回X一些列表中的顶级记录以及count响应头中的顶级记录X-Total-Count:

using System;
using System.Linq;
using System.Net;
using Microsoft.AspNetCore.Mvc;

namespace WebApplication.Controllers
{
    [Route("api")]
    public class ValuesController : Controller
    {
        [HttpGet]
        [Route("values/{top}")]
        public IActionResult Get(int top)
        {
            // Generate dummy values
            var list = Enumerable.Range(0, DateTime.Now.Second)
                                 .Select(i => $"Value {i}")
                                 .ToList();
            list.Reverse();

            var result = new ObjectResult(list.Take(top))
            {
                StatusCode = (int)HttpStatusCode.OK
            };

            Response.Headers.Add("X-Total-Count", list.Count.ToString());

            return result;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

URL看起来http://localhost:3377/api/values/5和结果(生成19条虚拟记录,因此X-Total-Count值为19)如下:

["Value 18","Value 17","Value 16","Value 15","Value 14"]
Run Code Online (Sandbox Code Playgroud)

  • 基类[`Microsoft.AspNetCore.Mvc.Controller`](https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.mvc.controller?view=aspnetcore-2.1)已包含属性“响应”。因此,除了调用`Request.HttpContext.Response.Headers`之外,还可以简单地调用`Response.Headers`。 (6认同)
  • 它感觉很hacky因为我们基本上设置结果,然后在2个地方设置属性.它可以封装在自定义操作结果中.在我打字时,我正要创建一个ContentResultWithHeaders.但话说回来,感觉就像很多努力. (2认同)

Hos*_*aei 28

对于任何想要为所有请求添加自定义标头的人来说,中间件是最好的方法。像这样在startup.cs中做一些改变:

app.Use(async (context, next) =>
{
   context.Response.Headers.Add("X-Developed-By", "Your Name");
   await next.Invoke();
});
Run Code Online (Sandbox Code Playgroud)

祝你好运。

  • 不鼓励直接在中间件中修改响应,请参阅[此处](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.2#create-a-middleware-pipeline-with -iapplicationbuilder-1)。相反,您可以使用“context.Response.OnStarting”回调。 (7认同)
  • @Mojtaba,直接在中间件中修改响应没有任何错误和不鼓励。该文档实际上提供了这样做的示例。但应该在调用“next”之前完成。警告仅针对这一点:调用“next”后不应修改响应。 (2认同)

Sim*_*ver 15

自定义属性可能是一个好方法。

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.2

public class AddHeaderAttribute : ResultFilterAttribute
{
    private readonly string _name;
    private readonly string _value;

    public AddHeaderAttribute(string name, string value)
    {
        _name = name;
        _value = value;
    }

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        context.HttpContext.Response.Headers.Add(_name, new string[] { _value });
        base.OnResultExecuting(context);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的 API 方法上像这样使用它

[AddHeader("X-MyHeader", "123"]
Run Code Online (Sandbox Code Playgroud)

如果你有一个公共头,你可以扩展这个类:

public class MySpecialHeaderAttribute : AddHeaderAttribute
{
    public MySpecialHeaderAttribute() : base("X-MyHeader", "true")
    {
    }
}
Run Code Online (Sandbox Code Playgroud)


Moj*_*aba 14

我同意@Ho3Ein的观点

如果你想为所有请求添加自定义标头,中间件是最好的方法

但不鼓励Resposne直接在中间件中进行修改(在调用之后)。next.Invoke()来自微软文档

响应开始后对 HttpResponse 进行更改,引发异常。例如,设置标头和状态代码等更改会引发异常。

app.Use(async (context, next) =>
        {
            // Do work that doesn't write to the Response.
            await next.Invoke();
            // Do logging or other work that doesn't write to the Response.
        });
Run Code Online (Sandbox Code Playgroud)

因此,在中间件中添加自定义标头的更好方法是使用Response.OnStarting回调,如下所示:

app.Use(async (context, next) =>
                      {

                          context.Response.OnStarting(() =>
                              {
                                  context.Response.Headers.Add("X-Developed-By", "Your Name");
                                  return Task.FromResult(0);
                              });

                          await next();
                      }
                      );
Run Code Online (Sandbox Code Playgroud)


Bou*_*egh 10

其他中间件可能会在您设置标头后清除标头。为了确保添加标头,请在发送响应之前添加它们。

app.Use(async (context, next) => {
    context.Response.OnStarting(() => {
        context.Response.Headers.Add("X-Developed-By", "Your Name");
        return Task.FromResult(0);
    });

    await next();
});

Run Code Online (Sandbox Code Playgroud)

或者在真正的中间件中

app.Use(async (context, next) => {
    context.Response.OnStarting(() => {
        context.Response.Headers.Add("X-Developed-By", "Your Name");
        return Task.FromResult(0);
    });

    await next();
});

Run Code Online (Sandbox Code Playgroud)