Add custom header to all responses in Web API

后端 未结 8 979
我寻月下人不归
我寻月下人不归 2020-12-07 18:30

Simple question, and I am sure it has a simple answer but I can\'t find it.

I am using WebAPI and I would like to send back a custom header to all responses (server

相关标签:
8条回答
  • 2020-12-07 19:14

    Neither of the above two solutions worked for me. They wouldn't even compile. Here's what I did. Added:

    filters.Add(new AddCustomHeaderFilter());
    

    to RegisterGlobalFilters(GlobalFilterCollection filters) method in FiltersConfig.cs and then added

    public class AddCustomHeaderFilter : ActionFilterAttribute
    {
       public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
       {
           actionExecutedContext.HttpContext.Response.Headers.Add("ServerTime", DateTime.Now.ToString());
       }
    }
    
    0 讨论(0)
  • 2020-12-07 19:14

    According to my requirement, below single line of code serves the purpose.

    System.Web.HttpContext.Current.Response.Headers.Add("Key", "Value")
    
    0 讨论(0)
  • 2020-12-07 19:15

    For that you can use a custom ActionFilter (System.Web.Http.Filters)

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

    You can then apply the filter to all your controller's actions by adding this in the configuration in Global.asax for example :

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

    You can also apply the filter attribute to the action that you want without the global cofiguration line.

    0 讨论(0)
  • 2020-12-07 19:15

    Julian's answer led me to have to create the filter but only using the the System.Web (v4) and System.Web.Http (v5) namespace (MVC packages were not part of this particular project this was used on.)

    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");
        }
    }
    

    And add it to the global.asax to have it used on every controller/action

            GlobalConfiguration.Configuration.Filters.Add(new AddCustomHeaderActionFilterAttribute());
    
    0 讨论(0)
  • 2020-12-07 19:21

    It can be done by the messagehandler easily, it will handle both ok response and exception case.

     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;
        }
    }
    

    Add it in the config

     config.MessageHandlers.Add(new CustomHeaderHandler());
    
    0 讨论(0)
  • 2020-12-07 19:21

    I combined the normal and exception path in one class:

    public class CustomHeaderAttribute : FilterAttribute, IActionFilter, IExceptionFilter
    {
        private static string HEADER_KEY   { get { return "X-CustomHeader"; } }
        private static string HEADER_VALUE { get { return "Custom header value"; } }
    
        public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            return (new CustomHeaderAction() as IActionFilter).ExecuteActionFilterAsync(actionContext, cancellationToken, continuation);
        }
    
        public Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
        {
            return (new CustomHeaderException() as IExceptionFilter).ExecuteExceptionFilterAsync(actionExecutedContext, cancellationToken);
        }
    
        private class CustomHeaderAction: ActionFilterAttribute
        {
            public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
            {
                if (actionExecutedContext.Response != null)
                { 
                    actionExecutedContext.Response.Content.Headers.Add(HEADER_KEY, HEADER_VALUE);
                }
            }
        }
    
        private class CustomHeaderException : 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_KEY, HEADER_VALUE);
            }
        }
    }
    

    Nothing fancy but at least it gives me one place to control my additional headers. For now it's just static content but you could always hook it up to some sort of dictionary generator/factory.

    0 讨论(0)
提交回复
热议问题