我的目标是为每个传出的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
不是虚拟的。
那么 - 这里发生了什么?什么是解决这个问题的最佳方法?
答案 0 :(得分:2)
在我看来,媒体类型格式化程序只关注编码相关的标题。如果您要添加自定义标头,则应使用DelegatingHandler
或ActionFilter
。您可以全局应用(将它们插入配置类中的相应集合中)和后续操作。使用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());