【问题标题】:Extending from JsonMediaTypeFormatter to set customer headers doesn't work with http Accept header从 JsonMediaTypeFormatter 扩展以设置客户标头不适用于 http Accept 标头
【发布时间】:2014-07-07 06:25:24
【问题描述】:

我的目标是为每个传出的 JSON 响应添加某些自定义标头。为此,创建了一个从 SetDefaultContentHeaders JsonMediaTypeFormatter 扩展的类,并像这样覆盖 SetDefaultContentHeaders 方法:

public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
    base.SetDefaultContentHeaders(type, headers, mediaType);
    headers.Add("X-Answer", "42");
    headers.Add("X-Question", "Unknown");
}

然后我将派生的媒体类型格式化程序添加到格式化程序列表中:

config.Formatters.Insert(0, new MyMediaTypeFormatter());

而且这个解决方案似乎适用于某些请求,但不适用于其他请求。经过一番调查,我发现如果我在请求中包含“接受”标头,则响应中不包含我的自定义标头!这有点令人惊讶,因为响应类型仍然返回 application/json,表明我的格式化程序或默认的 json 格式化程序正在处理响应。我唯一能想到的是调用SetDefaultContentHeaders 的代码JsonMediaTypeFormatter,而SetDefaultContentHeaders 不是虚拟的。

那么 - 这里发生了什么?纠正这个问题的最佳方法是什么?

【问题讨论】:

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


    【解决方案1】:

    在我看来,媒体类型格式化程序只关心与编码相关的标头。如果要添加自定义标头,应使用DelegatingHandlerActionFilter。您可以全局应用(将它们插入到配置类的适当集合中),也可以按操作应用。例如,使用DelegatingHandler 如下所示:

    public class JsonHeaderHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage message, CancellationToken token)
        {
            var response = await base.SendAsync(message, token);
            IEnumerable<string> contentTypes;
    
            if(response.Headers.TryGetValues("Content-Type", out contentTypes)) 
            {
                // Check if there is an application/json Content-Type header
                // There should be 0 or 1, a call to FirstOrDefault() would be fine
                if(contentTypes.Any(ct => ct.Contains("application/json")))
                {
                    response.Headers.Add("X-Answer", "42");
                    response.Headers.Add("X-Question", "Unknown");
                }
            }
    
            return response;
        }
    }
    
    // And using HttpConfiguration configuration
    configuration.MessageHandlers.Add(new JsonHeaderHandler());
    

    【讨论】:

    • 一定会试一试的!我仍然很好奇为什么我给定的实现停止使用接受标头,但是解决症状绝对是向前迈出的一大步。
    • @Rollie 我在媒体类型格式化程序中遇到了自定义标头问题。我没有花时间去找出原因,因为还有其他替代方案。
    猜你喜欢
    • 2015-11-27
    • 1970-01-01
    • 2017-04-28
    • 2011-12-21
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多