zoukankan      html  css  js  c++  java
  • ASP.NET Web API 2 媒体类型格式化程序

    Ø  简介

    在之前的ASP.NET Web API 2 消息处理管道文章中有提到,在 Web API 的生命周期中,还包含比较中要的一部分,就是媒体类型格式化程序,该程序主要用于处理 Web API 中的请求和响应数据的格式处理,比如常用的有 JSONXML 处理程序等。

     

    Ø  提示:为了简单,下面称“媒体类型格式化程序”为“格式化程序”。本文主要涉及一下几点:

    1.   什么是格式化程序

    2.   设置默认格式化程序

    3.   根据参数决定响应数据格式(JSON/XML

    4.   JSON 格式化程序相关设置

    5.   XML 格式化程序相关设置

    6.   其他

     

    Ø  在开始之前,首先添加以下代码:

    1.   定义一个 CustomerResModel 模型

    /// <summary>

    /// 客户响应模型。

    /// </summary>

    public class CustomerResModel

    {

        public int Id { get; set; }

     

        public string Name { get; set; }

     

        public DateTime CreateTime { get; set; }

     

        public DateTime? UpdateTime { get; set; }

    }

     

    2.   再添加一个 CustomerController 控制器

    [RoutePrefix("api/customer")]

    public class CustomerController : ApiController

    {

        /// <summary>

        /// 客户数组。

        /// </summary>

        private static CustomerResModel[] Customers = new CustomerResModel[]

        {

            new CustomerResModel(){ Id = 1, Name = "爱奇艺", CreateTime = DateTime.Parse("2018-05-02"), UpdateTime = null },

            new CustomerResModel(){ Id = 2, Name = "腾讯视频", CreateTime = DateTime.Parse("2018-05-02 17:38:25"), UpdateTime = DateTime.Parse("2018-05-02 17:41:33") }

        };

     

        /// <summary>

        /// 获取客户。

        /// </summary>

        [Route("getCustomer"), HttpGet]

        public HttpResponseMessage GetCustomer(HttpRequestMessage request, int id)

        {

            var data = Customers.FirstOrDefault(o => o.Id == id);

            return request.CreateResponse(HttpStatusCode.OK, data);

        }

     

        /// <summary>

        /// 获取客户列表。

        /// </summary>

        [Route("getCustomers"), HttpGet]

        public CustomerResModel[] GetCustomers()

        {

            return Customers;

        }

    }

     

    1.   什么是格式化程序

    1)   格式化程序是一系列用于解析请求和响应数据的类,这些类都直接或间接继承于 System.Net.Http.Formatting.MediaTypeFormatter 抽象类。我们可根据自己的需要,个性化设置格式化程序的行为,或者重写格式化程序(本文暂且不涉及此内容)。

    2)   当一个请求到达时,消息处理程序会根据请求头中的 Content-Type 找到与之匹配的格式化程序,来解析请求数据。比如:Content-Type:application/json 则使用 System.Net.Http.Formatting.JsonMediaTypeFormatter 来解析。

    3)   同样,响应数据格式则根据请求头中的 Accept 类型,找到匹配的格式化程序,来解析响应数据,再转为字节流响应请求。当然 Web API 也支持以 URL 参数来映射需要的格式化程序。

     

    2.   设置默认格式化程序

    Web API 默认包含以下四种格式化程序,其中 JsonXML 格式化程序比较常用,如果请求头的 Accept 未指定期望接受的类型(也就是 Accept:*/*),Web API 则会按照格式化程序集合中的一个来解析,也就是索引为0的格式化程序。可以看到,这里第一个是 Json 格式化程序。

    clip_image002[1]

     

    1)   搞清楚原理之后就好办了,在 WebApiConfig.cs 中加入代码:

    var xmlFormatter = config.Formatters.XmlFormatter;

    config.Formatters.Remove(xmlFormatter);

    config.Formatters.Insert(0, xmlFormatter);

     

    2)   这样默认就为 XML 格式化程序了,发送请求:

    1.   URLGET /api/customer/getCustomers HTTP/1.1

    2.   Request Accept: */*

    3.   Response Content-Type: application/xml; charset=utf-8

    4.   Response Text:

    clip_image003[1]

     

    Ø  注意:在其他的一些博文中,有介绍采用下面两种方式,来设置默认格式化程序。

    1.   config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

    这种方式表示:XML 格式化程序为第一项,且请求头 Accept */* 时,并不会以 XML 格式响应。但是指定了 Accept:application/xml 或参数指定 xml 时,还是会以 XML 格式响应。

     

    2.   config.Formatters.Remove(config.Formatters.XmlFormatter);

    这种方式表示:直接将 XML 格式化程序移除,这样无论什么情况下都不能使用 XML 格式化程序了。所以,并不建议采用此方式

     

    3.   根据参数决定响应数据格式(JSON/XML

    1)   WebApiConfig.cs 中加入代码

    config.Formatters.JsonFormatter.MediaTypeMappings.Add(new System.Net.Http.Formatting.QueryStringMapping("t", "json", "application/json"));

    config.Formatters.XmlFormatter.MediaTypeMappings.Add(new System.Net.Http.Formatting.QueryStringMapping("t", "xml", "application/xml"));

     

    2)   发送请求

    1.   URLGET /api/customer/getCustomers?t=json HTTP/1.1

    2.   Request Accept: */*

    3.   Response Content-Type: application/json; charset=utf-8

    4.   Response Text:

    clip_image004[1]

     

    4.   JSON 格式化程序相关设置

    JSON 格式化程序的序列化相关设置,主要使用 config.Formatters.JsonFormatter.SerializerSettings 属性,而该属性是一个 Newtonsoft.Json.JsonSerializerSettings 类型,所以 Web API 是借用了 Newtonsoft.Json 来完成对 JSON 序列化和反序列化的操作。既然这样,掌握了 Newtonsoft.Json 的知识,JSON 格式化程序的相关设置也不再话下了,更多 Newtonsoft.Json 的运用可参考:http://www.cnblogs.com/abeam/p/8295765.html

     

    JSON 格式化程序分为单独设置 Action 和全局设置,下面分别演示这两种方式:

    1)   单独设置 Action

    1.   修改 GetCustomer 的代码

    var data = Customers.FirstOrDefault(o => o.Id == id);

    var formatter = new JsonMediaTypeFormatter();

    formatter.SerializerSettings.Formatting = Formatting.Indented;  //json 格式化

    formatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();   //json 成员以驼峰命名(首字母小写)

    formatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;  //忽略 null(空)值

    formatter.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss fff";  //日期格式化,默认:yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK

    formatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;  //忽略循环引用的成员

    return request.CreateResponse(HttpStatusCode.OK, data, formatter);  //注意:这里指定 formatter 后,请求参数尽管是t=xml,也将以json格式返回

     

    2.   调用 /api/customer/getCustomer?id=1 接口,将看到如下结果:

    clip_image005[1]

     

    2)   全局设置(应用到每个 Action 的请求)

    其实,与单独设置 Action 一样,只是这里的 JsonMediaTypeFormatter 对象并不是 new 出来的,是从全局格式化程序中取出来的,所以这里的设置是全局型的设置。这样就可能有一个疑问了,如果 Action 中设置了全局也设置了,以哪个设置为准,答案是以 Action 中提供的格式化程序为准(经验证)。

    1.   WebApiConfig.cs 中加入代码:

    var jsonFormatter = config.Formatters.OfType<System.Net.Http.Formatting.JsonMediaTypeFormatter>().First();

    设置代码与 Action 中的设置一致,就省略了

     

    2.   调用 /api/customer/getCustomers 接口,将看到如下结果:

    clip_image006[1]

     

    5.   XML 格式化程序相关设置

    其实,XML 格式化程序使用相对较少,所以,在有用到时再来研究吧~

     

    6.   其他

    1)   获取全局 System.Web.Http.HttpConfiguration 对象

    我们可以使用 System.Web.Http.GlobalConfiguration.Configuration 属性获取全局 HttpConfiguration 对象,该对象与 WebApiConfig.Register() 方法的 config 参数是同一个实例。例如,以下代码是同等的(设置日期格式化):

    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.IsoDateTimeConverter()

    {

        DateTimeFormat = "yyyy-MM-dd HH:mm:ss fff"

    });

    //同等于

    config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.IsoDateTimeConverter()

    {

        DateTimeFormat = "yyyy-MM-dd HH:mm:ss fff"

    });

     

    2)   设置(添加/删除)格式化程序所支持的媒体类型

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

  • 相关阅读:
    Struts2使用json中要注意的几点
    JS实现关闭当前子窗口,刷新父窗口
    oracle中rownum效率低的原因以及解决办法
    URL传中文参数引发的乱码问题
    oracle存储过程
    Map.keyset() 使用详解
    oracle跨库查询dblink的用法
    Java中getResourceAsStream的用法
    如何删除存在多个重复记录中的一个
    cocos2d里面如何实现mvc系列
  • 原文地址:https://www.cnblogs.com/abeam/p/8985472.html
Copyright © 2011-2022 走看看