[英]How to add custom header to ASP.NET Core Web API response
我正在将我的 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);
如何在 ASP.NET Core Web API 中添加自定义标头?
您可以从传入的 Http Request
中HttpContext
,并在调用 return 之前将您自己的自定义标头添加到Response
对象。
如果您希望自定义标头持续存在并添加到跨多个控制器的所有 API 请求中,则应考虑制作一个Middleware
组件来为您执行此操作,然后将其添加到Startup.cs的 Http 请求管道中
public IActionResult SendResponse()
{
Response.Headers.Add("X-Total-Count", "20");
return Ok();
}
有一个简单的GET
操作示例,它从某个列表返回前X
条记录以及响应标头X-Total-Count
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;
}
}
}
URL 看起来像http://localhost:3377/api/values/5
和结果(生成 19 个虚拟记录,因此X-Total-Count
值将是 19)如下:
["Value 18","Value 17","Value 16","Value 15","Value 14"]
对于任何想要为所有请求添加自定义标头的人来说,中间件是最好的方法。 在 startup.cs 中进行一些更改,如下所示:
app.Use(async (context, next) =>
{
context.Response.Headers.Add("X-Developed-By", "Your Name");
await next.Invoke();
});
祝你好运。
自定义属性可能是一个好方法。
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);
}
}
然后像这样在你的 API 方法上使用它
[AddHeader("X-MyHeader", "123")]
如果你有一个共同的标题,你可以扩展这个类:
public class MySpecialHeaderAttribute : AddHeaderAttribute
{
public MySpecialHeaderAttribute() : base("X-MyHeader", "true")
{
}
}
我同意@Ho3Ein 的观点
如果您想为所有请求添加自定义标头,中间件是最好的方法
但不鼓励直接在中间件中修改Resposne
。 来自微软文档。
响应开始后对 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.
});
因此,在中间件中添加自定义标头的更好方法是使用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();
}
);
其他中间件可能会在您设置标题后清除它们。 为确保您的标头已添加,请在发送响应之前添加它们。
app.Use(async (context, next) => {
context.Response.OnStarting(() => {
context.Response.Headers.Add("X-Developed-By", "Your Name");
return Task.FromResult(0);
});
await next();
});
或者在真正的中间件中
public class AddHeadersMiddleware : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
context.Response.OnStarting(() => {
context.Response.Headers.Add("X-Developed-By", "Your Name");
return Task.FromResult(0);
});
await next();
}
}
FWIW,如果你有一个ApiController
,而不是一个Controller
,你可以这样做:
public class InfoController : ApiController
{
// Without custom header
public IHttpActionResult MyMethod(..)
{
var myObject= GetMyResult();
return Ok(myObject);
}
// With custom header
public IHttpActionResult MyMethod(..)
{
var myObject = GetMyResult();
// inspired from https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/content-negotiation#how-content-negotiation-works
var negotiator = Configuration.Services.GetContentNegotiator();
var result = negotiator.Negotiate(typeof(TypeOfMyObject), Request, Configuration.Formatters);
var msg = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ObjectContent<TypeOfMyObject>(myObject, result.Formatter,result.MediaType.MediaType)
};
msg.Headers.Add("MyCustomHeader", "MyCustomHeaderValue");
return ResponseMessage(msg);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.