ASP. 2 14th Lesson--content Negotiation (content negotiation)

Source: Internet
Author: User

Objective

Before reading this article, you can also go to the ASP. NET Web API 2 series navigation to view http://www.cnblogs.com/aehyok/p/3446289.html

This article describes how the ASP. NET Web API implements content negotiation.

The HTTP specification (RFC 2616) defines content negotiation as "the process of selecting the best performance for a given response when multiple performance is available." The main mechanism for content negotiation in HTTP is the following request header:

    • Accept: respond to the types of media that can be received, such as "Application/json", "Application/xml", or custom media types, such as "Application/vnd.example+xml".
    • Accept-charset: A character set that can be received, such as "UTF-8" or "ISO 8859-1".
    • accept-encoding: content encoding that can be received, such as "gzip".
    • accept-language: preferred natural language, such as "en-us".

The server can also view additional options for HTTP requests. For example, if the request contains a X-requested-with header, which indicates that this is an AJAX request, the server may use JSON by default without the accept header.

This article examines how the Web API uses the accept and Accept-charset headers. (Currently, there is no built-in support for accept-encoding or accept-language.) )

Serialization of serialization--

If the Web API controller returns a CLR type of response, the pipeline (Request processing) serializes the return value and writes it to the HTTP response body.

For example, consider the following controller actions:

Public Product getproduct (int id) {    var item = _products. FirstOrDefault (p = = P.id = = ID);    if (item = = null)    {        throw new httpresponseexception (Httpstatuscode.notfound);    }    return item; }

The client may send such an HTTP request:

GET http://localhost.:21069/api/products/1 Http/1.1host:localhost.:21069accept:application/json, Text/javascript, */*; q=0.01

The server may send the following response:

http/1.1 Okcontent-type:application/json; charset=utf-8content-length:57connection:close{"Id": 1, "Name": "Gizmo", "Category": "Widgets", "Price": 1.99}

In this example, the client requests (specifies) JSON, Javascript, or "arbitrary format (*/*)". The server responds with a JSON representation of a product object. Note that the Content-type header in the response has been set to "Application/json".

The controller can also return a Httpresponsemessage object. To specify the CLR object for the response body, call the Createresponse extension method:

Public httpresponsemessage getproduct (int id) {    var item = _products. FirstOrDefault (p = = P.id = = ID);    if (item = = null)    {        throw new httpresponseexception (Httpstatuscode.notfound);    }    Return Request.createresponse (Httpstatuscode.ok, product);}

This option allows you to have more control over the details of the response. You can set the status code, add the HTTP header, and so on.

The object that serializes the resource is called a media formatter. The media formatter is derived from the Mediatypeformatter class. The Web API provides a media formatter for XML and JSON, so you can create a custom formatter to support other media types. More information on writing custom formatters http://www.cnblogs.com/aehyok/p/3460164.html.

Working mechanism of content negotiation

First, the pipeline gets the icontentnegotiator service for the httpconfiguration object. It will also get a list of media formatters for the httpconfiguration.formatters collection.

The pipeline then calls icontentnegotiatior.negotiate, where it is passed:

    • The type of object to serialize
    • Media Formatter Collection
    • HTTP request

The Negotiate method returns two pieces of information:

    • The formatter to use
    • The type of media used for the response

If the formatter is not found, the method returns null, and the client receives an HTTP 406 (non-acceptable) error.

The following code shows how the controller can invoke content negotiation directly:

Public httpresponsemessage getproduct (int id) {    var product = new Product ()         {id = id, Name = "Gizmo", Category = " Widgets ", Price = 1.99M};    Icontentnegotiator negotiator = this. Configuration.Services.GetContentNegotiator ();    Contentnegotiationresult result = negotiator. Negotiate (        typeof (Product), this. Request, this. Configuration.formatters);    if (result = = null)    {        var response = new Httpresponsemessage (httpstatuscode.notacceptable);        throw new Httpresponseexception (response));    }    return new Httpresponsemessage ()    {        Content = new Objectcontent<product> (            Product,                //What We are serializing (serialization of what)            result. Formatter,           //The Media Formatter (medium formatter            result. Mediatype.mediatype  //The MIME type (MIME types)    };}

The above code is equivalent to automatic completion of pipelines.

The default content contract

The Defaultcontentnegotiator class provides the default implementation of Icontentnegotiator . It uses several criteria for selecting a formatter.

First, the formatter must be able to serialize the type, which is checked by Mediatypeformatter.canwritetype .

Second, the Content Explorer examines each formatter and evaluates whether or not the formatter matches the HTTP request. To evaluate the match, the content manager examines two things for this formatter:

    • The supportedmediatypes collection, which contains a list of supported media types. The content renegotiation attempts to match this list against the requested accept header. Note that the Accept header can include scopes. For example, "Text/plain" can match "text/*" or "*/*"
    • The mediatypemappings collection, which contains a list of objects for an mediatypemapping object. The mediatypemapping class provides a generic way to match an HTTP request with a media type. For example, it can map a custom HTTP header to a specific media type.

If there are multiple matches, the match with the highest quality factor wins. For example:

Accept:application/json, Application/xml; q=0.9, */*; q=0.1

In this example, Application/json has an implied mass factor of 1.0, so it is better than application/xml.

If no match is found, the content renegotiation attempts to match the media type of the request body (when there is a request body). For example, if the request contains JSON data, the content renegotiation will find the JSON formatter.

If there is still no match, the content renegotiation simply picks up the first formatter that can serialize the type.

Select character encoding

After the formatter is selected, the content renegotiation chooses the best character encoding. By examining the supportedencodingsof the formatter and matching it (if any) according to the requested submission.

ASP. 2 14th Lesson--content Negotiation (content negotiation)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.