標籤:
http://www.cnblogs.com/r01cn/archive/2013/05/17/3083400.html
6.1 Media Formatters
6.1 媒體格式化器
本文引自:http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters
By Mike Wasson|March 8, 2012
Mike Wasson|日期:2012-3-8
This tutorial shows how support additional media formats in ASP.NET Web API.
本教程示範如何在ASP.NET Web API中支援額外的媒體格式。
6.1.1 Internet Media Types
6.1.1 Internet的媒體類型
A media type, also called a MIME type, identifies the format of a piece of data. In HTTP, media types describe the format of the message body. A media type consists of two strings, a type and a subtype. For example:
媒體類型,也叫做MIME類型,標識了一片資料的格式。在HTTP中,媒體類型描述了訊息體的格式。一個媒體類型由兩個字串組成:類型和子類型。例如:
- text/html
- image/png
- application/json
When an HTTP message contains an entity-body, the Content-Type header specifies the format of the message body. This tells the receiver how to parse the contents of the message body.
當一條HTTP訊息含有一個實體時,Content-Type(內容類型)前序指定訊息體的格式。這是告訴接收器如何解析訊息體的內容。
For example, if an HTTP response contains a PNG image, the response might have the following headers.
例如,如果一個HTTP響應含有一個PNG圖片,該響應可能會有以下前序。
HTTP/1.1 200 OKContent-Length: 95267Content-Type: image/png
When the client sends a request message, it can include an Accept header. The Accept header tells the server which media type(s) the client wants from the server. For example:
當用戶端發送一條請求訊息時,它可能包括一個Accept前序。Accept前序是告訴伺服器,用戶端希望從伺服器得到哪種媒體類型。例如:
Accept: text/html,application/xhtml+xml,application/xml
This header tells the server that the client wants either HTML, XHTML, or XML.
該前序告訴伺服器,用戶端希望得到的是HTML、XHTML,或XML。
In Web API, the media type determines how Web API serializes and deserializes the HTTP message body. There is built-in support for XML, JSON, and form-urlencoded data, and you can support additional media types by writing a media formatter.
在Web API中,媒體類型決定了Web API如何對HTTP訊息體進行序列化和解序列化。對於XML、JSON,以及URL編碼的表單資料,已有了內建的支援。而且,通過編寫媒體格式化器(Media Formatter),可以支援額外的媒體類型。
To create a media formatter, derive from one of these classes:
為了建立媒體格式化器,需從以下類進行派生:
- MediaTypeFormatter. This class uses asynchronous read and write methods.
MediaTypeFormatter。這個類使用了非同步讀寫方法
- BufferedMediaTypeFormatter. This class derives from MediaTypeFormatter but wraps the asynchronous read/write methods inside synchronous methods.
BufferedMediaTypeFormatter。這個類派生於MediaTypeFormatter,但將非同步讀寫方法封裝在同步方法之中。
Deriving from BufferedMediaTypeFormatter is simpler, because there is no asynchronous code, but it also means the calling thread can block during I/O.
從BufferedMediaTypeFormatter派生要更簡單些,因為沒有非同步代碼,但它也意味著在I/O期間可能會阻塞線程。
6.1.2 Creating a Media Formatter
6.1.2 建立媒體格式化器
The following example shows a media type formatter that can serialize a Product object to a comma-separated values (CSV) format. This example uses the Product type defined in the tutorial Creating a Web API that Supports CRUD Operations. Here is the definition of the Product object:
以下樣本示範了一個媒體類型格式化器,它可以將Product對象序列化成一個逗號分隔的值(CSV)格式。該樣本使用了“建立支援CRUD操作的Web API”教程(本系列教程的第2.1小節)中定義的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; } }}
To implement a CSV formatter, define a class that derives from BufferedMediaTypeFormater:
為了實現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 { }}
In the constructor, add the media types that the formatter supports. In this example, the formatter supports a single media type, "text/csv":
在其構造器中,要添加一個該格式化器所支援的媒體類型。在這個例子中,該格式化器只支援單一的媒體類型:“text/csv”:
public ProductCsvFormatter(){ // Add the supported media type. // 添加所支援的媒體類型 SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));}
Override the CanWriteType method to indicate which types the formatter can serialize:
重寫這個CanWriteType方法,以指示該格式化器可以序列化哪種類型:
public override bool CanWriteType(System.Type type){ if (type == typeof(Product)) { return true; } else { Type enumerableType = typeof(IEnumerable<Product>); return enumerableType.IsAssignableFrom(type); }}
In this example, the formatter can serialize single Product objects as well as collections of Product objects.
在這個例子中,格式化器可以序列化單個Product對象,以及Product對象集合。
Similarly, override the CanReadType method to indicate which types the formatter can deserialize. In this example, the formatter does not support deserialization, so the method simply returns false.
相應地,重寫CanReadType方法,以指示該格式化器可以解序列化哪種類型。在此例中,格式化器不支援解序列化,因此該方法簡單地返回false。
protected override bool CanReadType(Type type){ return false;}
Finally, override the WriteToStream method. This method serializes a type by writing it to a stream. If your formatter supports deserialization, also override the ReadFromStream method.
最後,重寫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;}
6.1.4 Adding the Media Formatter
6.1.4 添加媒體格式化器
To add a media type formatter to the Web API pipeline, use the Formatters property on the HttpConfiguration object.
為了將媒體類型格式化器添加到Web API管線,要使用HttpConfiguration對象上的Formatters屬性。
public static void ConfigureApis(HttpConfiguration config){ config.Formatters.Add(new ProductCsvFormatter()); }
For ASP.NET hosting, add this function to the Global.asax file and call it from the Application_Start method.
對於ASP.NET託管,要將這個函數添加到Global.asax檔案,並通過Application_Start方法調用它。
protected void Application_Start(){ ConfigureApis(GlobalConfiguration.Configuration);
// ...}
Now if a client specifies "text/csv" in the Accept header, the server will return the data in CSV format.
現在,如果用戶端在Accept前序指定“text/csv”,則伺服器將返回CSV格式的資料。
The following example uses HttpClient to get the CSV data and write it to a file:
以下樣本使用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教程】6.1 媒體格式化器