扩展MediaTypeFormatter选择

时间:2013-04-26 16:39:19

标签: .net asp.net-mvc asp.net-web-api

在某些情况下,我想手动选择MediaTypeFormatter。有没有办法做到这一点?

例如,如果用户代理是Opera,则始终以JSON格式返回数据

1 个答案:

答案 0 :(得分:1)

当然,您可以创建自定义MediaTypeMapping并添加到格式化程序中。

以下示例:

config.Formatters.JsonFormatter.MediaTypeMappings.Add(new UserAgentMediaTypeMapping("Chrome", "application/json"));

-----------------------------------------------------

public class UserAgentMediaTypeMapping : MediaTypeMapping
{
    private string _userAgent;

    public UserAgentMediaTypeMapping(string userAgent, string mediaType)
        : base(mediaType)
    {
        //todo: error check

        _userAgent = userAgent.ToLowerInvariant();
    }

    public UserAgentMediaTypeMapping(string userAgent, MediaTypeHeaderValue mediaType)
        : base(mediaType)
    {
        //todo: error check

        _userAgent = userAgent.ToLowerInvariant();
    }

    public string UserAgent 
    {
        get
        {
            return _userAgent;
        }
    }

    public override double TryMatchMediaType(HttpRequestMessage request)
    {
        HttpHeaderValueCollection<ProductInfoHeaderValue> agents = request.Headers.UserAgent;

        foreach (ProductInfoHeaderValue pihv in agents)
        {
            if (pihv.Product != null)
            {
                if (pihv.Product.Name.ToLowerInvariant() == UserAgent)
                {
                    return 1.0;
                }
            }
        }

        return 0.0;
    }
}

来自我的旧博文(12)与con-neg 相关的更多信息:

当多个格式化程序符合传入请求的条件时会发生什么? Conneg算法选择哪一个?

在Conneg算法运行期间,基于一系列标准(如Request Accept标头,Content-Type标头,MediaTypeMapping等),总有可能多个格式化程序在写入Response时指示其可用性。可以想象,Conneg算法最终只能选择一个格式化程序。 Default Conneg算法具有以下优先顺序,用于选择最终格式化程序:

  1. 基于媒体类型映射的格式化程序匹配。
  2. 格式化程序匹配基于请求接受标头的媒体类型。
  3. 格式化程序匹配基于请求内容类型标头的媒体类型。
  4. 格式化程序匹配基于它是否可以序列化响应数据的类型。