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

Mod*_*ika 55 c# asp.net asp.net-web-api

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

我正在使用WebAPI,我想向所有响应发回自定义标头(开发人员请求的服务器日期/时间用于同步目的).

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


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

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

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

配置行:

config.Filters.Add(new ServerTimeHeaderFilter());
Run Code Online (Sandbox Code Playgroud)

Tom*_*uλa 95

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

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

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

GlobalConfiguration.Configuration.Filters.Add(new AddCustomHeaderFilter());
Run Code Online (Sandbox Code Playgroud)

您还可以在不使用全局配置行的情况下将filter属性应用于所需的操作.

  • 这个答案大多是正确的.有时,响应的内容可能是"null".你应该做`actionExecutedContext.Response.Headers.Add`. (2认同)
  • 这些答案的问题在于它们只将标题应用于 html 页面,而不是 CSS 页面、图像、javascript 等。这真的是一个问题吗?如果您使用 ZAP 运行渗透测试,它会抱怨缺少标头。如何为 MVC 应用程序中的所有文件添加标头? (2认同)

jul*_*ian 6

上述两种解决方案都不适合我.他们甚至不会编译.这就是我做的.添加:

filters.Add(new AddCustomHeaderFilter());
Run Code Online (Sandbox Code Playgroud)

RegisterGlobalFilters(GlobalFilterCollection filters)FiltersConfig.cs中的方法,然后添加

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


Hun*_*oir 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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

        GlobalConfiguration.Configuration.Filters.Add(new AddCustomHeaderActionFilterAttribute());
Run Code Online (Sandbox Code Playgroud)


War*_*mak 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

并在您的WebApi设置中:

configuration.Filters.Add(new HeaderAdderExceptionFilter());
Run Code Online (Sandbox Code Playgroud)

这种方法有效,因为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);
    }
}
Run Code Online (Sandbox Code Playgroud)

并在您的WebApi设置中:

configuration.Services.Replace(typeof(IExceptionHandler), new HeaderAdderExceptionHandler());
Run Code Online (Sandbox Code Playgroud)

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

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