6.1 media formatters
6.1 media formatter
This article cited from: http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters
By Mike Wasson | March 8, 2012
Author: Mike Wasson | Date:
This tutorial shows how support additional media formats in ASP. NET web API.
This tutorial demonstrates how to support additional media formats in ASP. NET Web APIs.
6.1.1 Internet media types
6.1.1 Internet media type
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:
Media type, also called MIME type, identifies the format of a piece of data. In HTTP, the media type describes the message body format. A media type consists of two strings: type and child type. For example:
- 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 caller how to parse the contents of the message body.
When an HTTP message contains an entity, the Content-Type Header specifies the message body format. This tells the receiver how to parse the content of the message body.
For example, if an HTTP response contains a PNG image, the response might have the following headers.
For example, if an HTTP response contains a PNG image, the response may have the following header.
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:
When a client sends a request message, it may contain an accept header. The accept header tells the server which media type the client wants to obtain from the server. For example:
Accept: text/html, application/XHTML + XML, application/XML
This header tells the server that the client wants either HTML, XHTML, or XML.
This header tells the server that what the client wants is HTML, XHTML, or 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.
In Web APIs, the media type determines how the web API serializes and deserializes HTTP message bodies. Built-in support for XML, JSON, and URL-encoded form data is provided. In addition, media formatter supports additional media types.
To create a media formatter, derive from one of these classes:
To create a media formatter, You need to derive from the following classes:
- Mediatypeformatter. This class uses asynchronous read and write methods.
Mediatypeformatter. This class uses the asynchronous read/write Method
- Bufferedmediatypeformatter. This class derives fromMediatypeformatterBut wraps the asynchronous read/write METHODS Inside synchronous methods.
Bufferedmediatypeformatter. This class is derived fromMediatypeformatterBut the asynchronous read/write method is encapsulated in the synchronous method.
Deriving from bufferedmediatypeformatter is simpler, because there is no asynchronous code, but it also means the calling thread can block during I/O.
It is easier to derive from bufferedmediatypeformatter because there is no asynchronousCodeBut it also means that the thread may be blocked during I/O.
6.1.2 creating a media formatter
6.1.2 create a media formatter
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:
The following example demonstrates a media formatter that serializes a product object into a comma-separated value (CSV) format. This example uses the product type defined in the "Create a web API that supports crud operations" tutorial (section 2.1 of this series of tutorials. The following is the definition of the product object:
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:
To implement the CSV formatter, You need to define a class derived from 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 ":
In its constructor, you need to add a media type supported by the formatter. In this example, the formatter only supports a single media type: "text/CSV ":
Public productcsvformatter () {// Add the supported media type. // Add the supported media type supportedmediatypes. Add (New mediatypeheadervalue ("text/CSV "));}
Override the canwritetype method to indicate which types the formatter can serialize:
Override the canwritetype method to indicate which type the formatter can serialize:
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.
In this example, The formatter can serialize a single product object and a collection of product objects.
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.
Correspondingly, override the canreadtype method to indicate which type the formatter can serialize. In this example, the formatter does not support deserialization, so this method simply returns false.
Protected override bool canreadtype (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.
Finally, rewrite the writetostream method. This method serializes a type into a stream. If your formatter supports deserialization, you can also rewrite the readfromstream method.
Public override void writetostream (type, object value, 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. // serialize the product into a CSV-format helper method private void writeitem (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 Add a media formatter
To add a media type formatter to the web API pipeline, use the formatters property on the httpconfiguration object.
To add the media formatter to the web API pipeline, you must use the formatters attribute on the httpconfiguration object.
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.
For ASP. NET hosting, you need to add this function to the Global. asax file and call it through the application_start method.
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.
Now, if the client specifies "text/CSV" in the accept header, the server returns CSV data.
The following example uses httpclient to get the CSV data and write it to a file:
The following example uses httpclient to obtain CSV data and write it into a file:
Httpclient client = new httpclient ();
// Add the accept header 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 .) // obtain the result and write it to the file // (port number 9000 is just a sample port number) string result = client. getstringasync ("http: // localhost: 9000/API/product /"). result; system. io. file. writealltext ("products.csv", result );
after reading this article, please give recommended