ASP.NET Web API 2.1에서 BSON 지원BSON Support in ASP.NET Web API 2.1

Mike Wassonby Mike Wasson

이 항목에서는 Web API 컨트롤러 (서버 쪽) 및 .NET 클라이언트 앱에서 BSON을 사용 하는 방법을 보여 줍니다.This topic shows how to use BSON in your Web API controller (server side) and in a .NET client app. Web API 2.1는 BSON을 지원 합니다.Web API 2.1 introduces support for BSON.

BSON 이란?What is BSON?

Bson 은 이진 serialization 형식입니다.BSON is a binary serialization format. "BSON"은 "이진 JSON"을 나타내지만 BSON 및 JSON은 매우 다르게 직렬화 됩니다."BSON" stands for "Binary JSON", but BSON and JSON are serialized very differently. BSON은 JSON과 유사 하 게 이름-값 쌍으로 표현 되기 때문에 "JSON과 유사 합니다."입니다.BSON is "JSON-like", because objects are represented as name-value pairs, similar to JSON. JSON과 달리 숫자 데이터 형식은 문자열이 아닌 바이트로 저장 됩니다.Unlike JSON, numeric data types are stored as bytes, not strings

BSON은 간단 하 고 쉽게 검색할 수 있도록 설계 되었으며 인코드/디코드 속도가 빠릅니다.BSON was designed to be lightweight, easy to scan, and fast to encode/decode.

  • BSON은 JSON의 크기와 비교할 수 있습니다.BSON is comparable in size to JSON. 데이터에 따라, BSON 페이로드는 JSON 페이로드보다 작거나 클 수 있습니다.Depending on the data, a BSON payload may be smaller or larger than a JSON payload. 이미지 파일 등의 이진 데이터를 serialize 하는 경우에는 이진 데이터가 b a s e 64로 인코딩되지 않으므로 BSON은 JSON 보다 작습니다.For serializing binary data, such as an image file, BSON is smaller than JSON, because the binary data is not base64-encoded.
  • 요소에 길이 필드가 접두사로 사용 되므로 BSON 문서를 쉽게 검색할 수 있으므로 파서는 요소를 디코딩하지 않고 건너뛸 수 있습니다.BSON documents are easy to scan because elements are prefixed with a length field, so a parser can skip elements without decoding them.
  • 숫자 데이터 형식은 문자열이 아닌 숫자로 저장 되기 때문에 인코딩과 디코딩을 효율적입니다.Encoding and decoding are efficient, because numeric data types are stored as numbers, not strings.

.NET 클라이언트 앱과 같은 네이티브 클라이언트는 JSON 또는 XML과 같은 텍스트 기반 형식 대신 BSON을 사용 하 여 이점을 누릴 수 있습니다.Native clients, such as .NET client apps, can benefit from using BSON in place of text-based formats such as JSON or XML. JavaScript가 JSON 페이로드를 직접 변환할 수 있으므로 browser 클라이언트의 경우 JSON을 사용 하는 것이 좋습니다.For browser clients, you will probably want to stick with JSON, because JavaScript can directly convert the JSON payload.

다행히 웹 API는 콘텐츠 협상을 사용 하므로 api에서 두 형식을 모두 지원 하 고 클라이언트에서 선택 하도록 할 수 있습니다.Fortunately, Web API uses content negotiation, so your API can support both formats and let the client choose.

서버에서 BSON 사용Enabling BSON on the Server

Web API 구성에서 포맷터 컬렉션에 BsonMediaTypeFormatter 를 추가 합니다.In your Web API configuration, add the BsonMediaTypeFormatter to the formatters collection.

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 포맷터를 사용 합니다.Now if the client requests "application/bson", Web API will use the BSON formatter.

BSON을 다른 미디어 유형과 연결 하려면 SupportedMediaTypes 컬렉션에 추가 합니다.To associate BSON with other media types, add them to the SupportedMediaTypes collection. 다음 코드에서는 지원 되는 미디어 형식에 "application/vnd. contoso"를 추가 합니다.The following code adds "application/vnd.contoso" to the supported media types:

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

예제 HTTP 세션Example HTTP Session

이 예제에서는 다음 모델 클래스와 간단한 Web API 컨트롤러를 사용 합니다.For this example, we'll use the following model class plus a simple Web API controller:

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 요청을 보낼 수 있습니다.A client might send the following HTTP request:

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

응답은 다음과 같습니다.Here is the response:

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

여기서는 이진 데이터를 "로 바꿨습니다." 문자.Here I've replaced the binary data with "." characters. Fiddler의 다음 스크린샷은 원시 16 진수 값을 보여 줍니다.The following screen shot from Fiddler shows the raw hex values.

HttpClient에서 BSON 사용Using BSON with HttpClient

.NET 클라이언트 앱은 Httpclient에서 bson 포맷터를 사용할 수 있습니다..NET clients apps can use the BSON formatter with HttpClient. Httpclient에 대 한 자세한 내용은 .Net 클라이언트에서 Web API 호출을 참조 하십시오.For more information about HttpClient, see Calling a Web API From a .NET Client.

다음 코드는 BSON을 수락 하는 GET 요청을 보낸 다음 응답에서 BSON 페이로드를 deserialize 합니다.The following code sends a GET request that accepts BSON, and then deserializes the BSON payload in the response.

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"으로 설정 합니다.To request BSON from the server, set the Accept header to "application/bson":

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

응답 본문을 deserialize 하려면 BsonMediaTypeFormatter을 사용 합니다.To deserialize the response body, use the BsonMediaTypeFormatter. 이 포맷터는 기본 포맷터 컬렉션에 없으므로 응답 본문을 읽을 때 해당 포맷터를 지정 해야 합니다.This formatter is not in the default formatters collection, so you have to specify it when you read the response body:

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

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

다음 예제에서는 BSON이 포함 된 POST 요청을 보내는 방법을 보여 줍니다.The next example shows how to send a POST request that contains 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();
    }
}

이 코드의 대부분은 이전 예제와 동일 합니다.Much of this code is the same as the previous example. 그러나 Postasync 메서드에서 BsonMediaTypeFormatter 을 포맷터로 지정 합니다.But in the PostAsync method, specify BsonMediaTypeFormatter as the formatter:

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

최상위 기본 형식 직렬화Serializing Top-Level Primitive Types

모든 BSON 문서는 키/값 쌍의 목록입니다. BSON 사양은 정수 또는 문자열과 같은 단일 원시 값을 serialize 하는 구문을 정의 하지 않습니다.Every BSON document is a list of key/value pairs.The BSON specification does not define a syntax for serializing a single raw value, such as an integer or string.

이 제한을 해결 하기 위해 BsonMediaTypeFormatter 는 기본 형식을 특수 한 경우로 처리 합니다.To work around this limitation, the BsonMediaTypeFormatter treats primitive types as a special case. Serialize 하기 전에 값을 키/값 쌍으로 변환 하 고 키를 "Value"로 변환 합니다.Before serializing, it converts the value into a key/value pair with the key "Value". 예를 들어 API 컨트롤러가 정수를 반환 한다고 가정 합니다.For example, suppose your API controller returns an integer:

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

직렬화 하기 전에 BSON 포맷터는이를 다음 키/값 쌍으로 변환 합니다.Before serializing, the BSON formatter converts this to the following key/value pair:

{ "Value": 42 }

Deserialize 할 때 포맷터는 데이터를 원래 값으로 다시 변환 합니다.When you deserialize, the formatter converts the data back to the original value. 그러나 웹 API에서 원시 값을 반환 하는 경우 다른 BSON 파서를 사용 하는 클라이언트는이 경우를 처리 해야 합니다.However, clients using a different BSON parser will need to handle this case, if your web API returns raw values. 일반적으로 원시 값이 아닌 구조화 된 데이터를 반환 하는 것을 고려해 야 합니다.In general, you should consider returning structured data, rather than raw values.

추가 리소스Additional Resources

Web API BSON 샘플Web API BSON Sample

미디어 포맷터Media Formatters