序列化与内容协商

时间:2021-12-17 02:18:53

1 多媒体格局化器

多媒体类型又叫MIME类型,指示了数据的格局。在HTTP协议中多媒体类型描述了动静体的格局。一个多媒体类型包孕两个字符串:类型和子类型。

例如:

text/htmlimage/pngapplication/jsonapplication/pdf

请求的Content-Type标头指定动静体的格局,指示接收者应如何解析动静体内容。

例如:请求奉告处事端请求数据类型为HTML, XHTML, or XML

请求:Accept: text/html,application/xhtml+xml,application/xml

响应:

HTTP/1.1 200 OK

Content-Length: 95267

Content-Type: image/png

多媒体类型为Web Api指明了如何序列化与反序列化HTTP动静体。Web API内建对XML, JSON, BSONform-urlencoded撑持,可以创建多媒体格局化器来自界说格局化方法,自界说的格局化器担任自MediaTypeFormatterBufferedMediaTypeFormatter,此中MediaTypeFormatter使用异步的读写要领,BufferedMediaTypeFormatter使用同步的读写要领。

 

例:创建CSV格局化器

界说实体

public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } }

界说ProductCsvFormatter,担任自BufferedMediaTypeFormatter

public class ProductCsvFormatter : BufferedMediaTypeFormatter { public ProductCsvFormatter() { // 添加被撑持的多媒体类型 SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv")); } }

重写CanWriteType要领,指明格局化器可序列化的类型

public override bool CanWriteType(System.Type type) { //指明可序列化Product if (type == typeof(Product)) { return true; } //指明可序列化IEnumerable<Product> else { Type enumerableType = typeof(IEnumerable<Product>); return enumerableType.IsAssignableFrom(type); } }

重写CanReadType要领,指明格局化器可反序列化的类型

public override bool CanReadType(Type type) { //设置为不撑持反序列化 return false; }

重写WriteToStream要领,这个要领将序列化数据写入流,若要撑持反序列化可重写ReadFromStream要领。

public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content) { using (var writer = new StreamWriter(writeStream)) { 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); } } } // 辅佐要领 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[] { ,, \n, \r, " }; 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.WordStr("\"", "\"\"")); } else return field; }

将多媒体格局化器添加到Web API管道(要领在WebApiConfig类中)

public static void Register(HttpConfiguration config) { config.Formatters.Add(new ProductCsvFormatter()); }

字符编码

多媒体格局化器撑持多种编码,例如UTF-8ISO 8859-1