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 剖析器用戶端必須處理此案例。 一般而言,您應該考慮傳回結構化資料,而不是原始值。
其他資源
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應