共用方式為


ASP.NET Web API 2.1 中的 BSON 支援

本主題說明如何在 Web API 控制器中使用 BSON, (伺服器端) 和 .NET 用戶端應用程式。 Web API 2.1 引進 BSON 的支援。

什麼是 BSON?

BSON 是二進位序列化格式。 「BSON」 代表「二進位 JSON」,但 BSON 和 JSON 會以非常不同的方式序列化。 BSON 類似「JSON」,因為物件會以名稱/值組表示,類似于 JSON。 不同于 JSON,數值資料類型會儲存為位元組,而不是字串

BSON 的設計訴求是輕量型、容易掃描,以及快速編碼/解碼。

  • BSON 的大小相當於 JSON。 BSON 承載可能小於或大於 JSON 酬載,取決於資料。 若要序列化二進位資料,例如影像檔案,BSON 小於 JSON,因為二進位資料不是 base64 編碼的。
  • BSON 檔很容易掃描,因為元素前面加上長度欄位,因此剖析器可以略過元素,而不需要解碼。
  • 編碼和解碼有效率,因為數值資料類型會儲存為數字,而不是字串。

.NET 用戶端應用程式等原生用戶端可以受益于使用 BSON 取代以文字為基礎的格式,例如 JSON 或 XML。 針對瀏覽器用戶端,您可能會想要繼續使用 JSON,因為 JavaScript 可以直接轉換 JSON 承載。

幸運的是,Web API 會使用 內容交涉,因此您的 API 可以支援這兩種格式,並讓用戶端選擇。

在伺服器上啟用 BSON

在您的 Web API 組態中,將 BsonMediaTypeFormatter 新增至 formatters 集合。

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

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

現在,如果用戶端要求 「application/bson」,Web API 將會使用 BSON 格式器。

若要將 BSON 與其他媒體類型產生關聯,請將它們新增至 SupportedMediaTypes 集合。 下列程式碼會將 「application/vnd.contoso」 新增至支援的媒體類型:

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

範例 HTTP 會話

在此範例中,我們將使用下列模型類別加上簡單的 Web 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);
    }
}

用戶端可能會傳送下列 HTTP 要求:

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

以下是回應:

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.........

在這裡,我已將二進位資料取代為 「.」 字元。 Fiddler 的下列螢幕擷取畫面顯示原始十六進位值。

視窗窗格的螢幕擷取畫面,其中顯示二進位資料在頂端和中間綠色的原始十六進位值,以及底部的黑色。

搭配 HttpClient 使用 BSON

.NET 用戶端應用程式可以搭配 HttpClient使用 BSON 格式器。 如需 HttpClient的詳細資訊,請參閱 從 .NET 用戶端呼叫 Web API

下列程式碼會傳送接受 BSON 的 GET 要求,然後在回應中還原序列化 BSON 承載。

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);
    }
}

若要從伺服器要求 BSON,請將 Accept 標頭設定為 「application/bson」:

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

若要還原序列化回應本文,請使用 BsonMediaTypeFormatter。 此格式器不在預設格式子集合中,因此您必須在讀取回應本文時加以指定:

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

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

下一個範例示範如何傳送包含 BSON 的 POST 要求。

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();
    }
}

大部分的程式碼都與上一個範例相同。 但在 PostAsync 方法中,將 BsonMediaTypeFormatter 指定為格式器:

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

序列化基本類型Top-Level

每個 BSON 檔都是索引鍵/值組的清單。BSON 規格不會定義用來序列化單一原始值的語法,例如整數或字串。

為了因應這項限制, BsonMediaTypeFormatter 會將基本類型視為特殊案例。 序列化之前,它會將值轉換成索引鍵「值」的索引鍵/值組。 例如,假設您的 API 控制器傳回整數:

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

序列化之前,BSON 格式器會將此值轉換成下列索引鍵/值組:

{ "Value": 42 }

當您還原序列化時,格式器會將資料轉換成原始值。 不過,如果您的 Web API 傳回原始值,則使用不同的 BSON 剖析器用戶端必須處理此案例。 一般而言,您應該考慮傳回結構化資料,而不是原始值。

其他資源

Web API BSON 範例

媒體格式器