Podpora BSON v ASP.NET Web API 2.1

Toto téma ukazuje, jak používat BSON v kontroleru webového rozhraní API (na straně serveru) a v klientské aplikaci .NET. Webové rozhraní API 2.1 zavádí podporu BSON.

Co je BSON?

BSON je binární serializační formát. "BSON" znamená "Binary JSON", ale BSON a JSON jsou serializovány velmi odlišně. BSON je "jako JSON", protože objekty jsou reprezentovány jako páry název-hodnota, podobně jako JSON. Na rozdíl od JSON se číselné datové typy ukládají jako bajty, ne jako řetězce.

BSON byl navržen tak, aby byl jednoduchý, snadno se skenoval a rychle kódoval a dekódoval.

  • BSON je velikostí srovnatelná s JSON. V závislosti na datech může být datová část BSON menší nebo větší než datová část JSON. Pro serializaci binárních dat, jako je soubor obrázku, je BSON menší než JSON, protože binární data nejsou zakódovaná jako base64.
  • Dokumenty BSON se snadno kontrolují, protože prvky mají předponu pole délky, takže analyzátor může prvky přeskočit bez dekódování.
  • Kódování a dekódování jsou efektivní, protože číselné datové typy se ukládají jako čísla, ne jako řetězce.

Nativní klienti, jako jsou klientské aplikace .NET, můžou těžit z používání BSON místo textových formátů, jako jsou JSON nebo XML. U klientů prohlížeče budete pravděpodobně chtít zůstat u formátu JSON, protože JavaScript dokáže datovou část JSON převést přímo.

Webové rozhraní API naštěstí používá vyjednávání obsahu, takže vaše rozhraní API může podporovat oba formáty a nechat klienta zvolit.

Povolení BSON na serveru

V konfiguraci webového rozhraní API přidejte BsonMediaTypeFormatter do kolekce formátovačů.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Formatters.Add(new BsonMediaTypeFormatter());

        // Other Web API configuration not shown...
    }
}

Pokud teď klient požaduje "application/bson", webové rozhraní API použije formátovací modul BSON.

Chcete-li přidružit BSON k jiným typům médií, přidejte je do kolekce SupportedMediaTypes. Následující kód přidá "application/vnd.contoso" k podporovaným typům médií:

var bson = new BsonMediaTypeFormatter();
bson.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/vnd.contoso"));
config.Formatters.Add(bson);

Příklad relace HTTP

V tomto příkladu použijeme následující třídu modelu a jednoduchý kontroler webového rozhraní API:

public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }
    public decimal Price { get; set; }
    public DateTime PublicationDate { get; set; }
}

public class BooksController : ApiController
{
    public IHttpActionResult GetBook(int id)
    {
        var book = new Book()
        {
            Id = id,
            Author = "Charles Dickens",
            Title = "Great Expectations",
            Price = 9.95M,
            PublicationDate = new DateTime(2014, 1, 20)
        };

        return Ok(book);
    }
}

Klient může odeslat následující požadavek HTTP:

GET http://localhost:15192/api/books/1 HTTP/1.1
User-Agent: Fiddler
Host: localhost:15192
Accept: application/bson

Tady je odpověď:

HTTP/1.1 200 OK
Content-Type: application/bson; charset=utf-8
Date: Fri, 17 Jan 2014 01:05:40 GMT
Content-Length: 111

.....Id......Title.....Great Expectations..Author.....Charles Dickens..Price..........PublicationDate.........

Tady jsem binární data nahradil(a) znaky ".". Následující snímek obrazovky z Nástroje Fiddler ukazuje nezpracované šestnáctkové hodnoty.

Snímek obrazovky s podoknem okna zobrazující nezpracované šestnáctkové hodnoty binárních dat v zelené barvě nahoře a uprostřed a černé dole

Použití BSON s HttpClient

Aplikace klientů .NET můžou s HttpClient používat formátovací modul BSON. Další informace o HttpClient najdete v tématu Volání webového rozhraní API z klienta .NET.

Následující kód odešle požadavek GET, který přijímá BSON, a pak deserializuje datovou část BSON v odpovědi.

static async Task RunAsync()
{
    using (HttpClient client = new HttpClient())
    {
        client.BaseAddress = new Uri("http://localhost");

        // Set the Accept header for BSON.
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/bson"));

        // Send GET request.
        result = await client.GetAsync("api/books/1");
        result.EnsureSuccessStatusCode();

        // Use BSON formatter to deserialize the result.
        MediaTypeFormatter[] formatters = new MediaTypeFormatter[] {
            new BsonMediaTypeFormatter()
        };

        var book = await result.Content.ReadAsAsync<Book>(formatters);
    }
}

Pokud chcete požádat BSON ze serveru, nastavte hlavičku Accept na "application/bson":

client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new  
    MediaTypeWithQualityHeaderValue("application/bson"));

Chcete-li deserializovat tělo odpovědi, použijte BsonMediaTypeFormatter. Tento formátovací modul není ve výchozí kolekci formátovačů, takže ho musíte zadat při čtení textu odpovědi:

MediaTypeFormatter[] formatters = new MediaTypeFormatter[] {
    new BsonMediaTypeFormatter()
};

var book = await result.Content.ReadAsAsync<Book>(formatters);

Další příklad ukazuje, jak odeslat požadavek POST, který obsahuje BSON.

static async Task RunAsync()
{
    using (HttpClient client = new HttpClient())
    {
        client.BaseAddress = new Uri("http://localhost:15192");

        // Set the Accept header for BSON.
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/bson"));

        var book = new Book()
        {
            Author = "Jane Austen",
            Title = "Emma",
            Price = 9.95M,
            PublicationDate = new DateTime(1815, 1, 1)
        };

        // POST using the BSON formatter.
        MediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
        var result = await client.PostAsync("api/books", book, bsonFormatter);
        result.EnsureSuccessStatusCode();
    }
}

Většina tohoto kódu je stejná jako v předchozím příkladu. V metodě PostAsync ale jako formátovač zadejte BsonMediaTypeFormatter :

MediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
var result = await client.PostAsync("api/books", book, bsonFormatter);

Serializace Top-Level primitivní typy

Každý dokument BSON je seznamem párů klíč/hodnota. Specifikace BSON nedefinuje syntaxi pro serializaci jedné nezpracované hodnoty, jako je například celé číslo nebo řetězec.

Chcete-li obejít toto omezení, BsonMediaTypeFormatter považuje primitivní typy jako zvláštní případ. Před serializací převede hodnotu na pár klíč/hodnota s klíčem "Hodnota". Předpokládejme například, že kontroler rozhraní API vrátí celé číslo:

public class ValuesController : ApiController
{
    public IHttpActionResult Get()
    {
        return Ok(42);
    }
}

Před serializací převede formátovací modul BSON na následující pár klíč/hodnota:

{ "Value": 42 }

Při deserializaci formátovací modul převede data zpět na původní hodnotu. Klienti používající jiný analyzátor BSON ale budou muset tento případ zpracovat, pokud vaše webové rozhraní API vrátí nezpracované hodnoty. Obecně byste měli zvážit vrácení strukturovaných dat místo nezpracovaných hodnot.

Další materiály

Ukázka BSON webového rozhraní API

Formátovací moduly médií