ASP.NET Web API 2 ' de medya biçimleriMedia Formatters in ASP.NET Web API 2

, Mike te sonby Mike Wasson

Bu öğreticide, ASP.NET Web API 'sinde ek medya biçimlerinin nasıl destekleyeceği gösterilmektedir.This tutorial shows how to support additional media formats in ASP.NET Web API.

Internet medya türleriInternet Media Types

MIME türü olarak da bilinen bir medya türü, bir veri parçasının biçimini tanımlar.A media type, also called a MIME type, identifies the format of a piece of data. HTTP 'de medya türleri ileti gövdesinin biçimini tanımlarlar.In HTTP, media types describe the format of the message body. Medya türü iki dizeden oluşur, bir türü ve alt türü.A media type consists of two strings, a type and a subtype. Örneğin:For example:

  • metin/htmltext/html
  • resim/pngimage/png
  • uygulama/jsonapplication/json

Bir HTTP iletisi bir varlık gövdesi içerdiğinde, Content-Type üstbilgisi ileti gövdesinin biçimini belirtir.When an HTTP message contains an entity-body, the Content-Type header specifies the format of the message body. Bu, alıcıya ileti gövdesinin içeriğini ayrıştırmayı söyler.This tells the receiver how to parse the contents of the message body.

Örneğin, bir HTTP yanıtı bir PNG görüntüsü içeriyorsa, yanıt aşağıdaki üst bilgilere sahip olabilir.For example, if an HTTP response contains a PNG image, the response might have the following headers.

HTTP/1.1 200 OK
Content-Length: 95267
Content-Type: image/png

İstemci bir istek iletisi gönderdiğinde, bir Accept üst bilgisi içerebilir.When the client sends a request message, it can include an Accept header. Accept üst bilgisi sunucuya, istemcinin sunucudan istediği medya türlerini bildirir.The Accept header tells the server which media type(s) the client wants from the server. Örneğin:For example:

Accept: text/html,application/xhtml+xml,application/xml

Bu üst bilgi, sunucuya istemcinin HTML, XHTML veya XML istediğini söyler.This header tells the server that the client wants either HTML, XHTML, or XML.

Medya türü, Web API 'sinin HTTP ileti gövdesini serileştirerek ve serileştirmesi gerektiğini belirler.The media type determines how Web API serializes and deserializes the HTTP message body. Web API 'si, XML, JSON, BSON ve form-urlencoded verileri için yerleşik desteğe sahiptir ve medya biçimlendiriciyazarak ek medya türlerini destekleyebilirsiniz.Web API has built-in support for XML, JSON, BSON, and form-urlencoded data, and you can support additional media types by writing a media formatter.

Bir medya biçimlendirici oluşturmak için, bu sınıflardan birini türet:To create a media formatter, derive from one of these classes:

Bufferedmediatypeformatter 'dan türetme, zaman uyumsuz kod olmadığı için daha basittir, ancak aynı zamanda çağıran iş parçacığının g/ç sırasında engelleyebileceği anlamına gelir.Deriving from BufferedMediaTypeFormatter is simpler, because there is no asynchronous code, but it also means the calling thread can block during I/O.

Örnek: CSV medya biçimlendiricisi oluşturmaExample: Creating a CSV Media Formatter

Aşağıdaki örnek, bir ürün nesnesini bir virgülle ayrılmış değerler (CSV) biçimine seri hale getirebilen bir medya türü biçimlendirici gösterir.The following example shows a media type formatter that can serialize a Product object to a comma-separated values (CSV) format. Bu örnek, CRUD Işlemlerini destekleyen bir Web API 'Si oluşturmaöğreticisinde tanımlanan ürün türünü kullanır.This example uses the Product type defined in the tutorial Creating a Web API that Supports CRUD Operations. Ürün nesnesinin tanımı aşağıda verilmiştir:Here 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; }
    }
}

Bir CSV biçimlendirici uygulamak için, Bufferedmediatypeformatter'dan türeyen bir sınıf tanımlayın:To implement a CSV formatter, define a class that derives from BufferedMediaTypeFormatter:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using ProductStore.Models;

namespace ProductStore.Formatters
{
    public class ProductCsvFormatter : BufferedMediaTypeFormatter
    {
    }
}

Oluşturucuda, biçimlendiricinin desteklediği medya türlerini ekleyin.In the constructor, add the media types that the formatter supports. Bu örnekte, biçimlendirici tek bir medya türünü destekler "metin/CSV":In this example, the formatter supports a single media type, "text/csv":

public ProductCsvFormatter()
{
    // Add the supported media type.
    SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
}

Biçimlendiricinin seri hale getirebileceği türleri belirtmek için CanWriteType yöntemini geçersiz kılın:Override the CanWriteType method to indicate which types 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);
    }
}

Bu örnekte, biçimlendirici tek Product nesnelerinin yanı sıra Product nesne koleksiyonlarını seri hale getirebilirsiniz.In this example, the formatter can serialize single Product objects as well as collections of Product objects.

Benzer şekilde, biçimlendirici 'in seri durumdan çıkarabileceği türleri göstermek için CanReadType yöntemini geçersiz kılın.Similarly, override the CanReadType method to indicate which types the formatter can deserialize. Bu örnekte, biçimlendirici serisini kaldırma ' yı desteklemez, bu nedenle metot yalnızca falsedeğerini döndürür.In this example, the formatter does not support deserialization, so the method simply returns false.

public override bool CanReadType(Type type)
{
    return false;
}

Son olarak, WriteToStream yöntemini geçersiz kılın.Finally, override the WriteToStream method. Bu yöntem bir akışa yazarak bir türü seri hale getirir.This method serializes a type by writing it to a stream. Biçimlendirici seri durumdan çıkarmayı destekliyorsa ReadFromStream yöntemini de geçersiz kılın.If your formatter supports deserialization, also override the ReadFromStream method.

public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
{
    using (var writer = new StreamWriter(writeStream))
    {
        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);
        }
    }
}

// Helper methods for serializing Products to CSV format. 
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)
    {
        // Delimit the entire field with quotes and replace embedded quotes with "".
        return String.Format("\"{0}\"", field.Replace("\"", "\"\""));
    }
    else return field;
}

Web API ardışık düzenine medya biçimlendirici eklemeAdding a Media Formatter to the Web API Pipeline

Web API ardışık düzenine bir medya türü biçimlendirici eklemek için HttpConfiguration nesnesindeki Formatters özelliğini kullanın.To add a media type formatter to the Web API pipeline, use the Formatters property on the HttpConfiguration object.

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

Karakter kodlamalarıCharacter Encodings

İsteğe bağlı olarak, bir medya biçimlendiricisi UTF-8 veya ISO 8859-1 gibi birden çok karakter kodlamasını destekleyebilir.Optionally, a media formatter can support multiple character encodings, such as UTF-8 or ISO 8859-1.

Oluşturucuda, Supportedencotypes koleksiyonuna bir veya daha fazla System. Text. Encoding türü ekleyin.In the constructor, add one or more System.Text.Encoding types to the SupportedEncodings collection. Önce varsayılan kodlamayı yerleştirin.Put the default encoding first.

public ProductCsvFormatter()
{
    SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));

    // New code:
    SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
    SupportedEncodings.Add(Encoding.GetEncoding("iso-8859-1"));
}

WriteToStream ve ReadFromStream yöntemlerinde, tercih edilen karakter kodlamasını seçmek için MediaTypeFormatter. selectkarakterencoding ' i çağırın.In the WriteToStream and ReadFromStream methods, call MediaTypeFormatter.SelectCharacterEncoding to select the preferred character encoding. Bu yöntem, istek üst bilgilerini desteklenen Kodlamalar listesiyle eşleştirir.This method matches the request headers against the list of supported encodings. Akıştan okurken veya yazarken döndürülen kodlamayı kullanın:Use the returned Encoding when you read or write from the stream:

public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
{
    Encoding effectiveEncoding = SelectCharacterEncoding(content.Headers);

    using (var writer = new StreamWriter(writeStream, effectiveEncoding))
    {
        // Write the object (code not shown)
    }
}