将自定义标头添加到Web API中的所有响应

时间:2013-12-03 11:07:31

标签: c# asp.net asp.net-web-api

简单的问题,我确信它有一个简单的答案,但我找不到它。

我正在使用WebAPI,我想向所有响应发回一个自定义标头(开发人员请求服务器日期/时间以进行同步)。

我目前正在努力寻找一个明确的例子,说明如何在一个地方(通过global.asax或其他中心位置)为所有回复显示自定义标题。


接受了答案,这是我的过滤器(几乎相同)和我添加到WebApi配置的注册功能的行。

注意:DateTime的东西是NodaTime,没有真正的理由只是有兴趣看它。

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        actionExecutedContext.Response.Content.Headers.Add("ServerTime", Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime()).ToString());
    }

配置行:

config.Filters.Add(new ServerTimeHeaderFilter());

7 个答案:

答案 0 :(得分:89)

为此,您可以使用自定义ActionFilter(System.Web.Http.Filters

public class AddCustomHeaderFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
       actionExecutedContext.Response.Headers.Add("customHeader", "custom value date time");
    }
}

然后,您可以通过在Global.asax中的配置中添加过滤器来将过滤器应用于所有控制器的操作,例如:

GlobalConfiguration.Configuration.Filters.Add(new AddCustomHeaderFilter());

您也可以在没有全局配置行的情况下将过滤器属性应用于所需的操作。

答案 1 :(得分:6)

以上两种解决方案都不适合我。他们甚至不会编译。这就是我做的。补充:

filters.Add(new AddCustomHeaderFilter());
在FiltersConfig.cs中使用

RegisterGlobalFilters(GlobalFilterCollection filters)方法,然后添加

public class AddCustomHeaderFilter : ActionFilterAttribute
{
   public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
   {
       actionExecutedContext.HttpContext.Response.Headers.Add("ServerTime", DateTime.Now.ToString());
   }
}

答案 2 :(得分:6)

Julian的回答让我必须创建过滤器,但只使用System.Web(v4)和System.Web.Http(v5)命名空间(MVC包不是这个特定项目的一部分。)

using System.Web;
using System.Web.Http.Filters;
...
public class AddCustomHeaderActionFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        base.OnActionExecuted(actionExecutedContext);
        actionExecutedContext.ActionContext.Response.Headers.Add("name", "value");
    }
}

并将其添加到global.asax,以便在每个控制器/操作

上使用它
        GlobalConfiguration.Configuration.Filters.Add(new AddCustomHeaderActionFilterAttribute());

答案 3 :(得分:6)

此问题的先前答案不解决控制器操作引发异常时应采取的措施。有两种基本方法可以使其发挥作用:

添加例外过滤器

using System.Net;
using System.Net.Http;
using System.Web.Http.Filters;

public class HeaderAdderExceptionFilter : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        if (context.Response == null)
            context.Response = context.Request.CreateErrorResponse(
                HttpStatusCode.InternalServerError, context.Exception);

        context.Response.Content.Headers.Add("header", "value");
    }
}

并在您的WebApi设置中:

configuration.Filters.Add(new HeaderAdderExceptionFilter());

这种方法有效,因为WebApi的默认异常处理程序将发送在过滤器中创建的HttpResponseMessage,而不是构建自己的。

替换默认的异常处理程序:

using System.Net;
using System.Net.Http;
using System.Web.Http.ExceptionHandling;
using System.Web.Http.Results;

public class HeaderAdderExceptionHandler : ExceptionHandler
{
    public override void Handle(ExceptionHandlerContext context)
    {
        HttpResponseMessage response = context.Request.CreateErrorResponse(
            HttpStatusCode.InternalServerError, context.Exception);
        response.Headers.Add("header", "value");

        context.Result = new ResponseMessageResult(response);
    }
}

并在您的WebApi设置中:

configuration.Services.Replace(typeof(IExceptionHandler), new HeaderAdderExceptionHandler());

您不能同时使用这两者。好吧,你可以,但是处理程序永远不会做任何事情,因为过滤器已经将异常转换为响应。

非常重要的是要注意已编写,此代码会将所有异常详细信息发送到客户端。您可能不希望在生产中执行此操作,因此请检查CreateErrorResponse()上的所有可用重载并选择适合您需要的重载。

答案 4 :(得分:2)

根据我的要求,下面的单行代码即可达到目的。

System.Web.HttpContext.Current.Response.Headers.Add("Key", "Value")

答案 5 :(得分:1)

消息处理程序可以轻松完成此操作,它将处理正常响应和异常情况。

 public class CustomHeaderHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
       // add header to request if you want
        var response = await base.SendAsync(request, cancellationToken);
        response.Headers.Add("cutomKey", "cutomValue");
        return response;
    }
}

将其添加到配置中

 config.MessageHandlers.Add(new CustomHeaderHandler());

答案 6 :(得分:0)

在尝试向整个控制器添加新标头时,我遇到了相同的问题,只需添加“ services.AddHttpContextAccessor();”到startup.cs然后创建您的控制器

public class EnController : Controller{

        public EnController(IHttpContextAccessor myHttpAccessor)
        {

            myHttpAccessor.HttpContext.Response.Headers.Add("Content-Language", "en-US");

        }

       ... more methods here... 

}