C# 从JsonMediaTypeFormatter扩展到设置客户头不';不能使用http接受头

C# 从JsonMediaTypeFormatter扩展到设置客户头不';不能使用http接受头,c#,asp.net,asp.net-web-api,mediatypeformatter,C#,Asp.net,Asp.net Web Api,Mediatypeformatter,我的目标是为每个传出的JSON响应添加特定的自定义头。为此,创建了一个从SetDefaultContentHeaders JsonMediaTypeFormatter扩展的类,并重写SetDefaultContentHeaders方法,如下所示: public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) { bas

我的目标是为每个传出的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());
这个解决方案似乎适用于某些请求,但不适用于其他请求。经过一些调查,我发现如果我在请求中包含一个“Accept”头,那么响应中就不包含我的自定义头!这有点令人惊讶,因为响应类型仍然返回application/json,这表明我的格式化程序或默认的json格式化程序正在处理响应。我唯一能想到的是调用
SetDefaultContentHeaders
的代码在
JsonMediaTypeFormatter
中,并且
SetDefaultContentHeaders
不是虚拟的


那么-这是怎么回事?什么是纠正这一问题的最佳方法?

在我看来,媒体类型格式化程序只关心编码相关的头。如果要添加自定义标题,应使用或。您可以全局应用(将它们插入配置类中的适当集合中)和后续操作的每个操作。使用
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());
公共类JsonHeaderHandler:DelegatingHandler
{
受保护的覆盖异步任务SendAsync(
HttpRequestMessage消息,CancellationToken令牌)
{
var response=await base.sendaync(消息、令牌);
i可数内容类型;
if(response.Headers.TryGetValues(“内容类型”,out contentTypes))
{
//检查是否存在应用程序/json内容类型头
//应该有0或1,调用FirstOrDefault()就可以了
if(contentTypes.Any(ct=>ct.Contains(“application/json”))
{
回复。标题。添加(“X-Answer”、“42”);
回复。标题。添加(“X问题”、“未知”);
}
}
返回响应;
}
}
//以及使用HttpConfiguration配置
Add(新的JsonHeaderHandler());

一定会让你尝试一下!我仍然很好奇,为什么我给定的实现停止使用accept标头,但找到解决该症状的方法无疑是一个很好的进步。@Rollie我对媒体类型格式化程序中的自定义标头有问题。我还没有花时间去找出原因,因为有一个替代方案正在酝酿中。