ASP.NET Web API MediaTypeFormatter

MediaTypeFormatter提供了HTTP Request body data与.Net类型之间的无缝转换。

什么是MediaType

Media Type指的是HTTP header中的content-type,它定义了在HTTP Body中的数据的格式。Media Type也用于Http RequestHeader中的Accept头,表明改Request期望收到的Response的body的格式。

你可以使用标准的media type,比如application/json, application/xml。你也可以定义自己的media type.

什么是MediaTypeFormatter

MediaTypeFormatter用于在Http Body和.Net之间进行转换。

所有的MediaTypeFormatter都继承自抽象类MediaTypeFormatter

public abstract class MediaTypeFormatter
{
// properties public Collection<MediaTypeHeaderValue> SupportedMediaTypes { get; private set; } public Collection<Encoding> SupportedEncodings { get; private set; } public Collection<MediaTypeMapping> MediaTypeMappings { get; private set; } // methods public virtual Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger) { // to be overriden by base class } public virtual Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, TransportContext transportContext) { // to be overriden by base class } public abstract bool CanReadType(Type type); public abstract bool CanWriteType(Type type); }

要定义自己的MediaTypeFormatter,只需要实现上述抽象类即可。

这里有详细的例子

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

怎么使用自定义的formatter

要把一个media type formatter加入Web API Pipeline,

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

什么时候Web API Framework会用到MediaTypeFormatter

我们前面说过,media type主要用于HTTP Request/Response header中的content-type,和HTTP Request header中的Accept。

HTTP Request/Response header中的content-type

当Web API接收到HTTP Request请求,并且需要读取body信息时(比如,使用FromBody属性),Web API会检查content-type的类型,然后使用已注册的formatter去deserialize。

HTTP Request header中的Accept

假设我们有一个Product类

    [DataContract(Name = "Product", Namespace = "http://www.azure.com")]
    public class Product
    {
        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public string Category { get; set; }

        [DataMember]
        public decimal Price { get; set; }
    }

以及一个Web API的controller

public HttpResponseMessage Get()
{
     var product = new Product() { Id = 1, Name = "Gizmo", Category = "Widgets", Price = 1.99M };

     return Request.CreateResponse(HttpStatusCode.OK, product);
}

这个controller返回一个HttpResponseMessage对象,里面包含一个product。

此时,Web API会检查该Request的Header中Accept的内容,然后调用相应的formatter去序列号product对象。

我们可以使用fiddler发送以下request

User-Agent: Fiddler
Host: localhost:9664
Accept: application/xml

那么我们得到的response是

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sat, 18 Oct 2014 08:35:21 GMT
Content-Length: 187

<Product xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.azure.com"><Category>Widgets</Category><Id>1</Id><Name>Gizmo</Name><Price>1.99</Price></Product>

注意Content-Type,以及body的格式。

如果我们发送以下request

User-Agent: Fiddler
Host: localhost:9664
Accept: application/json

 

我们得到的response是

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcZWR3YW5nXGRvY3VtZW50c1x2aXN1YWwgc3R1ZGlvIDIwMTNcUHJvamVjdHNcV2ViQXBwVGVzdFxXZWJBcHBUZXN0XGFwaVx2YWx1ZXM=?=
X-Powered-By: ASP.NET
Date: Sat, 18 Oct 2014 09:22:45 GMT
Content-Length: 57

{"Id":1,"Name":"Gizmo","Category":"Widgets","Price":1.99}

 

Web API使用XmlMediaTypeFormatter处理xml media type。XmlMediaTypeFormatter默认使用DataContractSerializer进行序列化。

使用JsonMediaTypeFormatter处理json media type。JsonMediaTypeFormatter默认使用Json.net进行序列化。

 

转载于:https://www.cnblogs.com/wangguangxin/p/4033384.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值