Asp.Net Web API 2第十二課——Media Formatters媒體格式化器

來源:互聯網
上載者:User

標籤:

前言

閱讀本文之前,您也可以到Asp.Net Web API 2 系列導航進行查看 http://www.cnblogs.com/aehyok/p/3446289.html

本教程示範如何在ASP.NET Web API中支援額外的媒體格式。

Internet Media Types——Internet的媒體類型

媒體類型,也叫做MIME類型,標識了一片資料的格式。在HTTP中,媒體類型描述了訊息體的格式。一個媒體類型由兩個字串組成:類型和子類型。例如:

  • text/html
  • image/png
  • application/json

當一條HTTP訊息含有一個實體時,Content-Type(內容類型)前序指定訊息體的格式。這是告訴接收器如何解析訊息體的內容。

例如,如果一個HTTP響應含有一個PNG圖片,該響應可能會有以下前序。

HTTP/1.1 200 OKContent-Length: 95267Content-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期間可能會阻塞線程。

Creating a Media Formatter——建立媒體格式化器

 以下樣本示範了一個媒體類型格式化器,它可以將Product對象序列化成一個逗號分隔的值(CSV)格式。該樣本使用了Asp.Net Web API 2第二課——CRUD操作  http://www.cnblogs.com/aehyok/p/3434578.html中定義的Product類型。以下是Product對象的定義:

namespace ProductStore.Models{    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的類:

namespace ProductStore.Formatters{    using System;    using System.Collections.Generic;    using System.IO;    using System.Net.Http.Formatting;    using System.Net.Http.Headers;    using ProductStore.Models;    public class ProductCsvFormatter : BufferedMediaTypeFormatter     {    }}

在其構造器中,要添加一個該格式化器所支援的媒體類型。在這個例子中,該格式化器只支援單一的媒體類型:“text/csv”:

public ProductCsvFormatter(){    // Add the supported media type.    // 添加所支援的媒體類型    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();}// Helper methods for serializing Products to CSV format. // 將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;}

Adding the Media Formatter——添加媒體格式化器

 為了將媒體類型格式化器添加到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();// Add the Accept header// 添加Accept前序client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/csv"));// Get the result and write it to a file.// (Port 9000 is just an example port number.)// 擷取結果並將其寫入檔案// (連接埠號碼9000隻是一個樣本連接埠號碼)string result = client.GetStringAsync("http://localhost:9000/api/product/").Result;System.IO.File.WriteAllText("products.csv", result);

Asp.Net Web API 2第十二課——Media Formatters媒體格式化器

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.