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"));

  • 相关阅读:
    B.Icebound and Sequence
    Educational Codeforces Round 65 (Rated for Div. 2) D. Bicolored RBS
    Educational Codeforces Round 65 (Rated for Div. 2) C. News Distribution
    Educational Codeforces Round 65 (Rated for Div. 2) B. Lost Numbers
    Educational Codeforces Round 65 (Rated for Div. 2) A. Telephone Number
    Codeforces Round #561 (Div. 2) C. A Tale of Two Lands
    Codeforces Round #561 (Div. 2) B. All the Vowels Please
    Codeforces Round #561 (Div. 2) A. Silent Classroom
    HDU-2119-Matrix(最大匹配)
    读书的感想!
  • 原文地址:https://www.cnblogs.com/abeam/p/8985472.html
Copyright © 2011-2022 走看看