Media Formatters(媒体格式化器)
6.1.1 Internet的媒体类型
媒体类型,也叫做MIME类型,标识了数据的格式。在HTTP中,媒体类型描述了消息体的格式。一个媒体类型由两个字符串组成:类型和子类型。例如:
- 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报头是告诉服务器,客户端希望从服务器得到哪种媒体类型。例如:
Accept: text/html,application/xhtml+xml,application/xml
该报头告诉服务器,客户端希望得到的是HTML、XHTML,或XML。
在Web API中,媒体类型决定了Web API如何对HTTP消息体进行序列化和解序列化。对于XML、JSON,以及URL编码的表单数据,已有了内建的支持。而且,通过编写媒体格式化器(Media Formatter),可以支持额外的媒体类型。
为了创建媒体格式化器,需从以下类进行派生:
- MediaTypeFormatter。这个类使用了异步读写方法
- BufferedMediaTypeFormatter。这个类派生于MediaTypeFormatter,但将异步读写方法封装在同步方法之中。
从BufferedMediaTypeFormatter派生要更简单些,因为没有异步代码,但它也意味着在I/O期间可能会阻塞线程。
6.1.2 创建媒体格式化器
以下示例演示了一个媒体类型格式化器,它可以将Product对象序列化成一个逗号分隔的值(CSV)格式。该示例使用了“创建支持CRUD操作的Web API”教程中定义的Product类型。以下是Product对象的定义:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
为了实现CSV格式化器,要定义一个派生于BufferedMediaTypeFormater的类:
public class ProductCsvFormatter : BufferedMediaTypeFormatter
{
}
在其构造器中,要添加一个该格式化器所支持的媒体类型。在这个例子中,该格式化器只支持单一的媒体类型:“text/csv”:
public ProductCsvFormatter()
{
// 添加所支持的媒体类型
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
}
重写这个CanWriteType方法,以指示该格式化器可以序列化哪种类型:
public override bool CanWriteType(System.Type type)
{
if (type == typeof(Product))
{
return true;
}
else
{
Type enumerableType = typeof(IEnumerable<Product>);
return enumerableType.IsAssignableFrom(type);
}
}
在这个例子中,格式化器可以序列化单个Product对象,以及Product对象集合。
相应地,重写CanReadType方法,以指示该格式化器可以解序列化哪种类型。在此例中,格式化器不支持解序列化,因此该方法简单地返回false。
protected override bool CanReadType(Type type)
{
return false;
}
最后,重写WriteToStream方法。通过将一种类型写成一个流,该方法对该类型进行序列化。如果你的格式化器要支持解序列化,也可以重写ReadFromStream方法。
public override void WriteToStream(
Type type, object value, Stream stream, HttpContentHeaders contentHeaders)
{
using (var writer = new StreamWriter(stream))
{
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);
}
}
stream.Close();
} // 将Product序列化成CSV格式的辅助器方法
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)
{
return String.Format("\"{0}\"", field.Replace("\"", "\"\""));
}
else return field;
}
6.1.4 添加媒体格式化器
为了将媒体类型格式化器添加到Web API管线,要使用HttpConfiguration对象上的Formatters属性。
public static void ConfigureApis(HttpConfiguration config)
{
config.Formatters.Add(new ProductCsvFormatter());
}
对于ASP.NET托管,要将这个函数添加到Global.asax文件,并通过Application_Start方法调用它。
protected void Application_Start()
{
ConfigureApis(GlobalConfiguration.Configuration);
// ...
}
现在,如果客户端在Accept报头指定“text/csv”,则服务器将返回CSV格式的数据。
以下示例使用HttpClient来获取CSV数据,并将其写入一个文件:
HttpClient client = new HttpClient();
// 添加Accept报头
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/csv"));
// 获取结果并将其写入文件
// (端口号9000只是一个示例端口号)
string result = client.GetStringAsync("http://localhost:9000/api/product/").Result;
Media Formatters(媒体格式化器)的更多相关文章
- Media Formatters媒体格式化器
Media Formatters媒体格式化器 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/344 ...
- Asp.Net Web API 2第十二课——Media Formatters媒体格式化器
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本教程演示如何在ASP.N ...
- 【ASP.NET Web API教程】6.1 媒体格式化器
http://www.cnblogs.com/r01cn/archive/2013/05/17/3083400.html 6.1 Media Formatters6.1 媒体格式化器 本文引自:htt ...
- CSS3 之 Media(媒体查询器)
1.响应式Media(媒体查询器) (1)<link rel=“stylesheet” media=“screen and (max-width: 600px)” href=“small.css ...
- (原创)jQuery Media Plugin-jQuery的网页媒体播放器插件的使用心得
jQuery Media Plugin是一款基于jQuery的网页媒体播放器插件,它支持大部分的网络多媒体播放器和多媒体格式,比如:Flash, Windows Media Player, Real ...
- 总结一下响应式设计的核心CSS技术Media(媒体查询器)的用法。(转)
<meta http-equiv="X-UA-Compatible" content="IE=edge"><!--兼容ie-->< ...
- css3 media媒体查询器用法总结
随着响应式设计模型的诞生,Web网站又要发生翻天腹地的改革浪潮,可能有些人会觉得在国内IE6用户居高不下的情况下,这些新的技术还不会广泛的蔓延下去,那你就错了,如今淘宝,凡客,携程等等公司都已经在大胆 ...
- 与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成
原文:与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成 [索引页][源码下载] 与众不同 win ...
- css3 media媒体查询器用法总结 兼容ie8以下的方法
总结一下响应式设计的核心CSS技术Media(媒体查询器)的用法. http://www.360doc.com/content/14/0704/06/10734150_391862769.shtml ...
随机推荐
- [LOJ 6433][PKUSC 2018]最大前缀和
[LOJ 6433][PKUSC 2018]最大前缀和 题意 给定一个长度为 \(n\) 的序列, 求把这个序列随机打乱后的最大前缀和的期望乘以 \(n!\) 后对 \(998244353\) 取膜后 ...
- 24种设计模式-策略模式(Strategy Pattern)
一.优点: 1. 策略模式提供了管理相关的算法族的办法.策略类的等级结构定义了一个算法或行为族.恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码. 2. 策略模式提供了可以替换继承关系的 ...
- Java 基础系列:不变性
1.1 定义 不可变类(Immutable Objects):当类的实例一经创建,其内容便不可改变,即无法修改其成员变量. 可变类(Mutable Objects):类的实例创建后,可以修改其内容. ...
- python3 消耗CPU的性能,使CPU满载(可以设置进程名称)
需要安装库:setproctitle 1.1.10,设置进程名称,测试操作系统centos 7.0 # -*- coding: utf-8 -*- from multiprocessing im ...
- 三、ForkJoin分析
ForkJoin分析 一.ForkJoin ForkJoin是由JDK1.7后提供多线并发处理框架.ForkJoin的框架的基本思想是分而治之.什么是分而治之?分而治之就是将一个复杂的计算,按照设 ...
- mysql id 自增实现
1.在mysql中建表 2.使用: >insert into 表名 values(id,'www',66); 连续运行5次后结果: =============================== ...
- html-加水印--watermark--代码测试
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- redis之GeoHash
Redis 提供的 Geo 指令只有 6 个,它只是一个普通的 zset 结构. 增加geoadd 指令携带集合名称以及多个经纬度名称三元组,注意这里可以加入多个三元组127.0.0.1:6379&g ...
- MySQL for OPS 04:存储引擎
写在前面的话 在使用 Linux 的时候,可以经常听到有关文件系统 FS(File System)的东西,MySQL 也有属于自己类似的东西,那就是存储引擎.之前在创建数据表的时候,在 Create ...
- java架构之路(mysql底层原理)Mysql之Explain使用详解
上篇博客,我们详细的说明了mysql的索引存储结构,也就是我们的B+tree的变种,是一个带有双向链表的B+tree.那么我今天来详细研究一下,怎么使用索引和怎么查看索引的使用情况. 我们先来简单的建 ...