• Media Formatters in ASP.NET Web API 2


    原文:http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

    1. 网络媒体类型

    媒体类型,也叫作MIME类型,表示数据的格式。在HTTP中,MIME描述了消息体的格式。

    • MIME类型有两个字符串组成——类型和子类型。例如:
    text/html
    image/png
    application/json
    
    
    • 当HTTP消息包含一个数据体时,Content-Type 头部指出了数据体的格式。这告诉接收者怎么解析消息体。例如,如果HTTP响应包含一个PNG图片,那响应可能包含以下头部。
    HTTP/1.1 200 OK
    Content-Length: 95267
    Content-Type: image/png
    
    • 客户端可以包含Accept头部来发起一个请求。Accept头部告诉服务器客户端想要什么类型的MIME类型。例如:
    Accept: text/html,application/xhtml+xml,application/xml
    

    这个头部告诉服务器,客户端想要HTML,XHTML,或者XML。

    • MIME类型决定了WEB API怎么序列化和反序列化HTTP的消息体。WEB API有内置的MIME,支持XML,JSON,BSON,以及form-urlencoded数据,也可以通过自定义一个媒体格式。

    为了创建一个MIME格式,从以下其中一个类派生:

    • MediaTypeFormatter. 这个类使用异步的读写方法。

    • BufferedMediaTypeFormatter. 这个类从MediaTypeFormatter 派生,但是使用同步的读写方法。

    2. 示例:创建一个CSV媒体格式

    Steps:

    1. 创建一个ProductCsvFormatter
    2. 构造函数添加支持的媒体类型
    3. 重写CanWriteType,表明可以序列化的类型
    4. 重写CanReadType,表明可以反序列化的类型
    5. 重写WriteToStream,序列化的真正实现
    6. 将媒体格式添加到WEB API管道
    7. 添加字符编码支持,支持UTF-8,iso-8859-1
    8. 增加测试代码

    ProductCsvFormatter 代码片段

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net.Http;
    using System.Net.Http.Formatting;
    using System.Net.Http.Headers;
    using System.Text;
    using WebApiPractice.Models;
    
    namespace WebApiPractice.Formatters
    {
        //http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters
        //Step1
        public class ProductCsvFormatter: BufferedMediaTypeFormatter
        {
            public ProductCsvFormatter()
            {
                //Step2
                SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
    
                //Step7
                SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
                SupportedEncodings.Add(Encoding.GetEncoding("iso-8859-1"));
            }
    
            //Step3
            public override bool CanWriteType(Type type)
            {
                if(type == typeof(Product))
                {
                    return true;
                }
    
                Type enumerableType = typeof(IEnumerable<Product>);
                return enumerableType.IsAssignableFrom(type);
            }
    
            //Step4
            public override bool CanReadType(Type type)
            {
                return false;
            }
    
            //Step5
            public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
            {
                //Step7
                Encoding effectiveEncoding = SelectCharacterEncoding(content.Headers);
    
                using (var writer = new StreamWriter(writeStream, effectiveEncoding))
                {
                    var products = value as IEnumerable<Product>;
                    if (products != null)
                    {
                        foreach (var product in products)
                        {
                            WriteItem(product, writer);
                        }
                    }
                    else
                    {
                        var singleProduct = value as Product;
                        if (singleProduct == null)
                        {
                            throw new InvalidOperationException("Cannot serialize type");
                        }
                        WriteItem(singleProduct, writer);
                    }
                }
            }
    
            // Helper methods for serializing Products to CSV format. 
            private void WriteItem(Product product, StreamWriter writer)
            {
                writer.WriteLine("{0},{1},{2},{3}", Escape(product.Id),
                    Escape(product.Name), Escape(product.Category), Escape(product.Price));
            }
    
            static char[] _specialChars = new char[] { ',', '
    ', '
    ', '"' };
    
            private string Escape(object o)
            {
                if (o == null)
                {
                    return "";
                }
                string field = o.ToString();
                if (field.IndexOfAny(_specialChars) != -1)
                {
                    // Delimit the entire field with quotes and replace embedded quotes with "".
                    return String.Format(""{0}"", field.Replace(""", """"));
                }
                else return field;
            }
        }
    }
    

    WebApiConfig代码片段

    using System.Web.Http;
    using Microsoft.Owin.Security.OAuth;
    using WebApiPractice.Formatters;
    
    namespace WebApiPractice
    {
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                // Web API 配置和服务
                // 将 Web API 配置为仅使用不记名令牌身份验证。
                config.SuppressDefaultHostAuthentication();
                config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
    
                // Web API 路由
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
                //Step6,加入web api管道
                config.Formatters.Add(new ProductCsvFormatter());
            }
        }
    }
    
    

    测试代码

    using System;
    using System.Net.Http;
    using System.Net.Http.Headers;
    
    namespace WebApiPractice
    {
        public class WebApiRequestHelper
        {
            public void Start()
            {
                HttpClient httpClient = new HttpClient();
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/csv", 1));
    
                var t = httpClient.GetStringAsync("http://localhost:60865/api/products");
                t.Wait();
    
                System.Diagnostics.Debug.WriteLine(t.Result);
                Console.WriteLine(t.Result);
            }
        }
    }
    

    测试结果

    1,Tomato Soup,Groceries,1
    2,Yo-yo,Toys,3.75
    3,Hammer,Hardware,16.99
    
  • 相关阅读:
    usaco 1.3.1 Mixing Milk
    ACM必备(学完一个就加亮一个)不多,就这些!
    usaco1.2.4Palindromic Squares
    usaco 1.2.3 Name That Number
    coursera机器学习笔记机器学习概论,梯度下降法
    coursera机器学习笔记多元线性回归,normal equation
    coursera机器学习支持向量机SVM
    使用C/C++,赋值运算时发生的转换
    coursera机器学习logistic回归,正则化
    coursera机器学习笔记神经网络,初识篇
  • 原文地址:https://www.cnblogs.com/pengzhen/p/5836832.html
Copyright © 2020-2023  润新知