ASP.NET Core MVC에서 응답 데이터 서식 지정 소개Introduction to formatting response data in ASP.NET Core MVC

작성자: Steve SmithBy Steve Smith

ASP.NET Core MVC에는 지정된 형식을 사용하거나 클라이언트 사양에 대한 응답으로 응답 데이터의 서식을 지정하기 위한 기본적인 지원 기능이 있습니다.ASP.NET Core MVC has built-in support for formatting response data, using fixed formats or in response to client specifications.

GitHub에서 샘플을 보거나 다운로드합니다.View or download sample from GitHub.

형식별 작업 결과Format-Specific Action Results

일부 작업 결과 형식은 JsonResultContentResult와 같이 특정 형식과 관련됩니다.Some action result types are specific to a particular format, such as JsonResult and ContentResult. 작업은 항상 특정한 방식으로 형식이 지정된 특정 결과를 반환할 수 있습니다.Actions can return specific results that are always formatted in a particular manner. 예를 들어 JsonResult 반환은 클라이언트 기본 설정에 관계 없이 JSON 형식의 데이터를 반환하게 됩니다.For example, returning a JsonResult will return JSON-formatted data, regardless of client preferences. 마찬가지로, ContentResult 반환은 일반 텍스트 형식 문자열 데이터를 반환합니다(단순히 문자열을 반환).Likewise, returning a ContentResult will return plain-text-formatted string data (as will simply returning a string).

참고

작업은 특정 형식을 반환할 필요가 없습니다. MVC는 모든 개체 반환 값을 지원합니다.An action isn't required to return any particular type; MVC supports any object return value. 작업이 IActionResult 구현을 반환하고 컨트롤러가 Controller에서 상속하는 경우, 개발자는 많은 선택 사항에 해당하는 도우미 메서드를 다양하게 선택할 수 있습니다.If an action returns an IActionResult implementation and the controller inherits from Controller, developers have many helper methods corresponding to many of the choices. IActionResult 형식이 아닌 개체를 반환하는 작업의 결과는 적절한 IOutputFormatter 구현을 사용하여 직렬화됩니다.Results from actions that return objects that are not IActionResult types will be serialized using the appropriate IOutputFormatter implementation.

데이터를 Controller 기본 클래스에서 상속하는 컨트롤러의 특정 형식으로 반환하려면 기본 제공 도우미 메서드 Json을 사용하여 일반 텍스트에 대해 Content 및 JSON을 반환합니다.To return data in a specific format from a controller that inherits from the Controller base class, use the built-in helper method Json to return JSON and Content for plain text. 작업 메서드는 특정 결과 형식(예: JsonResult) 또는 IActionResult를 반환해야 합니다.Your action method should return either the specific result type (for instance, JsonResult) or IActionResult.

JSON 형식의 데이터 반환:Returning JSON-formatted data:

// GET: api/authors
[HttpGet]
public JsonResult Get()
{
    return Json(_authorRepository.List());
}

이 작업에서 샘플 응답:Sample response from this action:

응답의 콘텐츠 형식이 application/json임이 표시된 Microsoft Edge에 있는 개발자 도구의 네트워크 탭

응답의 콘텐츠 형식은 application/json이며, 네트워크 요청 목록과 Response 헤더 섹션에 모두 표시됩니다.Note that the content type of the response is application/json, shown both in the list of network requests and in the Response Headers section. 또한 Request 헤더 섹션의 Accept 헤더에서 브라우저(이 경우 Microsoft Edge)에 의해 제공되는 옵션의 목록입니다.Also note the list of options presented by the browser (in this case, Microsoft Edge) in the Accept header in the Request Headers section. 현재 기술은 이 헤더를 무시합니다. 이를 따르는 데 관해서는 아래에 설명되어 있습니다.The current technique is ignoring this header; obeying it is discussed below.

서식 있는 일반 텍스트 데이터를 반환하려면 ContentResultContent 도우미를 사용합니다.To return plain text formatted data, use ContentResult and the Content helper:

// GET api/authors/about
[HttpGet("About")]
public ContentResult About()
{
    return Content("An API listing authors of docs.asp.net.");
}

이 작업에서 응답:A response from this action:

응답의 콘텐츠 형식이 text/plain임이 표시된 Microsoft Edge에 있는 개발자 도구의 네트워크 탭

이 경우는 반환된 Content-Typetext/plain입니다.Note in this case the Content-Type returned is text/plain. 또한 문자열 응답 형식을 사용하여 이것과 동일한 동작을 얻을 수 있습니다.You can also achieve this same behavior using just a string response type:

// GET api/authors/version
[HttpGet("version")]
public string Version()
{
    return "Version 1.0.0";
}

여러 반환 형식 또는 옵션이 포함된 특수 작업의 경우(예: 수행되는 작업의 결과를 기반으로 하는 다른 HTTP 상태 코드) 반환 형식으로 IActionResult를 선호합니다.For non-trivial actions with multiple return types or options (for example, different HTTP status codes based on the result of operations performed), prefer IActionResult as the return type.

콘텐츠 협상Content Negotiation

콘텐츠 협상(줄여서 conneg)은 클라이언트가 Accept 헤더를 지정하는 경우에 발생합니다.Content negotiation (conneg for short) occurs when the client specifies an Accept header. ASP.NET Core MVC에서 사용하는 기본 형식은 JSON입니다.The default format used by ASP.NET Core MVC is JSON. 콘텐츠 협상은 ObjectResult에 의해 구현됩니다.Content negotiation is implemented by ObjectResult. 또한 도우미 메서드에서 반환된 상태 코드별 작업 결과 상태 코드에 기본적으로 제공됩니다(모두 ObjectResult 기반).It's also built into the status code specific action results returned from the helper methods (which are all based on ObjectResult). 또한 모델 형식(데이터 전송 형식으로 정의된 클래스)을 반환할 수 있으며, 프레임워크는 사용자를 위해 자동으로 ObjectResult에 래핑합니다.You can also return a model type (a class you've defined as your data transfer type) and the framework will automatically wrap it in an ObjectResult for you.

다음 작업 메서드는 OkNotFound 도우미 메서드를 사용합니다.The following action method uses the Ok and NotFound helper methods:

// GET: api/authors/search?namelike=th
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
    var result = _authorRepository.GetByNameSubstring(namelike);
    if (!result.Any())
    {
        return NotFound(namelike);
    }
    return Ok(result);
}

다른 형식이 요청되지 않는 한 JSON 형식 응답이 반환되고 서버는 요청된 형식을 반환할 수 있습니다.A JSON-formatted response will be returned unless another format was requested and the server can return the requested format. Fiddler와 같은 도구를 사용하여 Accept 헤더가 포함된 요청을 만들고 다른 형식을 지정할 수 있습니다.You can use a tool like Fiddler to create a request that includes an Accept header and specify another format. 해당 경우에서 서버에 요청된 형식으로 응답을 생성할 수 있는 포맷터가 있으면 결과는 클라이언트 기본 형식으로 반환됩니다.In that case, if the server has a formatter that can produce a response in the requested format, the result will be returned in the client-preferred format.

application/xml의 Accept 헤더 값과 함께 수동으로 만든 GET 요청을 보여 주는 Fiddler 콘솔

위의 스크린 샷에서 Accept: application/xml을 지정하며 요청을 생성하는 데 Fiddler 작성기가 사용되었습니다.In the above screenshot, the Fiddler Composer has been used to generate a request, specifying Accept: application/xml. 기본적으로 ASP.NET Core MVC는 JSON만 지원하므로 다른 형식이 지정된 경우라도 결과는 여전히 JSON 형식입니다.By default, ASP.NET Core MVC only supports JSON, so even when another format is specified, the result returned is still JSON-formatted. 다음 섹션에서는 추가적인 포맷터를 추가하는 방법이 나옵니다.You'll see how to add additional formatters in the next section.

컨트롤러 작업은 POCO(Plain Old CLR Objects)를 반환할 수 있습니다. 그런 경우 ASP.NET MVC는 사용자를 위해 개체를 래핑하는 ObjectResult를 자동으로 만듭니다.Controller actions can return POCOs (Plain Old CLR Objects), in which case ASP.NET MVC will automatically create an ObjectResult for you that wraps the object. 클라이언트는 서식 있는 직렬화된 개체를 가져옵니다. (JSON 형식이 기본값이며, XML 또는 다른 형식을 구성할 수 있습니다.)The client will get the formatted serialized object (JSON format is the default; you can configure XML or other formats). 반환되는 개체가 null이면, 프레임워크는 204 No Content 응답을 반환합니다.If the object being returned is null, then the framework will return a 204 No Content response.

개체 형식 반환하기:Returning an object type:

// GET api/authors/ardalis
[HttpGet("{alias}")]
public Author Get(string alias)
{
    return _authorRepository.GetByAlias(alias);
}

이 샘플에서는 유효한 작성자 별칭에 대한 요청이 작성자의 데이터로 200 정상 응답을 받게 됩니다.In the sample, a request for a valid author alias will receive a 200 OK response with the author's data. 잘못된 별칭에 대한 요청은 204 콘텐츠 없음 응답을 받게 됩니다.A request for an invalid alias will receive a 204 No Content response. XML 및 JSON 형식의 응답을 보여 주는 스크린샷은 다음과 같습니다.Screenshots showing the response in XML and JSON formats are shown below.

콘텐츠 협상 프로세스Content Negotiation Process

콘텐츠 협상Accept 헤더가 요청에 나타나는 경우에만 발생합니다.Content negotiation only takes place if an Accept header appears in the request. 요청에 accept 헤더가 포함되어 있는 경우 프레임워크는 기본 설정 순서대로 accept 헤더의 미디어 유형을 열거하고, accept 헤더에 의해 지정된 형식 중 하나로 응답을 생성할 수 있는 포맷터를 찾으려고 시도합니다.When a request contains an accept header, the framework will enumerate the media types in the accept header in preference order and will try to find a formatter that can produce a response in one of the formats specified by the accept header. 클라이언트의 요청을 충족할 수 있는 포맷터가 없는 경우 프레임워크는 응답을 생성할 수 있는 첫 번째 포맷터를 찾으려고 시도합니다(개발자가 대신 406 허용되지 않음을 반환하도록 MvcOptions에서 옵션을 구성하지 않을 경우).In case no formatter is found that can satisfy the client's request, the framework will try to find the first formatter that can produce a response (unless the developer has configured the option on MvcOptions to return 406 Not Acceptable instead). 이 요청은 XML을 지정하나, XML 포맷터가 구성되지 않은 경우에는 JSON 포맷터가 사용됩니다.If the request specifies XML, but the XML formatter has not been configured, then the JSON formatter will be used. 더 일반적으로 요청된 형식을 제공할 수 있는 포맷터가 구성되지 않은 경우에는 개체의 서식을 지정할 수 있는 첫 번째 포맷터가 사용됩니다.More generally, if no formatter is configured that can provide the requested format, then the first formatter that can format the object is used. 헤더가 없으면 반환될 개체를 처리할 수 있는 첫 번째 포맷터가 응답을 직렬화하는 데 사용됩니다.If no header is given, the first formatter that can handle the object to be returned will be used to serialize the response. 이 경우 모든 협상이 발생하지 않으므로 서버에서 어떤 형식이 사용될지를 결정합니다.In this case, there isn't any negotiation taking place - the server is determining what format it will use.

참고

Accept 헤더에 */*가 포함되는 경우, RespectBrowserAcceptHeaderMvcOptions에서 true로 설정되지 않으면 헤더는 무시됩니다.If the Accept header contains */*, the Header will be ignored unless RespectBrowserAcceptHeader is set to true on MvcOptions.

브라우저 및 콘텐츠 협상Browsers and Content Negotiation

일반적인 API 클라이언트와 달리 웹 브라우저는 와일드카드를 비롯한 다양한 형식 범위를 포함하는 Accept 헤더를 제공합니다.Unlike typical API clients, web browsers tend to supply Accept headers that include a wide array of formats, including wildcards. 기본적으로 프레임워크가 브라우저에서 오는 요청을 감지하면 Accept 헤더를 무시하고, 대신에 콘텐츠를 응용 프로그램에 구성된 기본 형식으로 반환합니다(달리 구성되지 않은 경우 JSON).By default, when the framework detects that the request is coming from a browser, it will ignore the Accept header and instead return the content in the application's configured default format (JSON unless otherwise configured). 이는 API를 통해 다양한 브라우저를 사용하는 경우에 더 일관된 환경을 제공합니다.This provides a more consistent experience when using different browsers to consume APIs.

응용 프로그램 적용 브라우저 accept 헤더를 선호하는 경우, Startup.csConfigureServices 메서드에서 RespectBrowserAcceptHeadertrue로 설정하여 MVC 구성의 일부로 구성할 수 있습니다.If you would prefer your application honor browser accept headers, you can configure this as part of MVC's configuration by setting RespectBrowserAcceptHeader to true in the ConfigureServices method in Startup.cs.

services.AddMvc(options =>
{
    options.RespectBrowserAcceptHeader = true; // false by default
});

포맷터 구성Configuring Formatters

응용 프로그램이 기본 JSON 외에 추가 형식을 지원해야 하는 경우 NuGet 패키지를 추가하고 이를 지원하도록 MVC를 구성할 수 있습니다.If your application needs to support additional formats beyond the default of JSON, you can add NuGet packages and configure MVC to support them. 입력 및 출력에 대한 개별 포맷터가 있습니다.There are separate formatters for input and output. 입력 포맷터는 모델 바인딩에서 사용되며, 출력 포맷터는 응답 형식을 지정하는 데 사용됩니다.Input formatters are used by Model Binding; output formatters are used to format responses. 사용자 지정 포맷터를 구성할 수 있습니다.You can also configure Custom Formatters.

XML 형식 지원 추가Adding XML Format Support

XML 서식 지정에 대한 지원을 추가하려면 Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet 패키지를 설치합니다.To add support for XML formatting, install the Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet package.

Startup.cs에서 MVC의 구성에 XmlSerializerFormatters를 추가합니다.Add the XmlSerializerFormatters to MVC's configuration in Startup.cs:

services.AddMvc()
    .AddXmlSerializerFormatters();

또는 출력 포맷터만 추가할 수 있습니다.Alternately, you can add just the output formatter:

services.AddMvc(options =>
{
    options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});

이러한 두 방법은 System.Xml.Serialization.XmlSerializer를 사용하여 결과를 직렬화합니다.These two approaches will serialize results using System.Xml.Serialization.XmlSerializer. 원하는 경우 연결된 해당 포맷터를 추가하여 System.Runtime.Serialization.DataContractSerializer를 사용할 수 있습니다.If you prefer, you can use the System.Runtime.Serialization.DataContractSerializer by adding its associated formatter:

services.AddMvc(options =>
{
    options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
});

XML 서식 지정에 대한 지원을 추가하면 컨트롤러 메서드는 요청의 Accept 헤더에 따라 적절한 형식을 반환해야 합니다. 이 Fiddler 예제에서는 다음과 같습니다.Once you've added support for XML formatting, your controller methods should return the appropriate format based on the request's Accept header, as this Fiddler example demonstrates:

Fiddler 콘솔: 요청에 대한 Raw 탭에 Accept 헤더 값이 application/xml임이 표시됩니다.

Inspectors 탭에서 Accept: application/xml 헤더 집합으로 Raw GET 요청이 만들어진 것을 확인할 수 있습니다.You can see in the Inspectors tab that the Raw GET request was made with an Accept: application/xml header set. 응답 창에 Content-Type: application/xml 헤더 및 XML로 직렬화된 Author 개체가 표시됩니다.The response pane shows the Content-Type: application/xml header, and the Author object has been serialized to XML.

Accept 헤더에서 application/json을 지정하도록 요청을 수정하려면 Composer 탭을 사용합니다.Use the Composer tab to modify the request to specify application/json in the Accept header. 요청을 실행하면 응답이 JSON으로 형식이 지정됩니다.Execute the request, and the response will be formatted as JSON:

Fiddler 콘솔: 요청에 대한 Raw 탭에 Accept 헤더 값이 application/json임이 표시됩니다.

이 스크린 샷에는 요청이 Accept: application/json의 헤더를 설정하고, 응답이 해당 Content-Type과 동일하게 지정하는 것을 확인할 수 있습니다.In this screenshot, you can see the request sets a header of Accept: application/json and the response specifies the same as its Content-Type. Author 개체가 JSON 형식으로 응답 본문에 표시됩니다.The Author object is shown in the body of the response, in JSON format.

특정 형식 적용Forcing a Particular Format

특정 작업에 대한 응답 형식을 제한하려는 경우 [Produces] 필터를 적용하여 수행할 수 있습니다.If you would like to restrict the response formats for a specific action you can, you can apply the [Produces] filter. [Produces] 필터는 특정 작업(또는 컨트롤러)에 대한 응답 형식을 지정합니다.The [Produces] filter specifies the response formats for a specific action (or controller). 대부분 필터와 마찬가지로, 작업, 컨트롤러 또는 전역 범위에 적용할 수 있습니다.Like most Filters, this can be applied at the action, controller, or global scope.

[Produces("application/json")]
public class AuthorsController

[Produces] 필터는 다른 포맷터가 응용 프로그램에 구성되고 클라이언트가 다른 사용 가능한 형식을 요청하는 Accept 헤더를 제공하는 경우에도 JSON 형식의 응답을 반환하도록 AuthorsController 내에서 모든 작업을 강제로 수행합니다.The [Produces] filter will force all actions within the AuthorsController to return JSON-formatted responses, even if other formatters were configured for the application and the client provided an Accept header requesting a different, available format. 필터를 전역에서 적용하는 방법을 비롯한 자세한 내용은 필터를 참조하세요.See Filters to learn more, including how to apply filters globally.

특수한 사례 포맷터Special Case Formatters

일부 특수한 경우 기본 제공 포맷터를 사용하여 구현됩니다.Some special cases are implemented using built-in formatters. 기본적으로 string 반환 형식은 text/plain(Accept 헤더를 통해 요청된 경우 text/html)으로 형식이 지정됩니다.By default, string return types will be formatted as text/plain (text/html if requested via Accept header). 이 동작은 TextOutputFormatter를 제거하여 삭제할 수 있습니다.This behavior can be removed by removing the TextOutputFormatter. 포맷터는 Startup.csConfigure 메서드에서 제거합니다(아래 참조).You remove formatters in the Configure method in Startup.cs (shown below). 모델 개체 반환 형식이 있는 작업은 null을 반환하는 경우 204 콘텐츠 없음 응답을 반환합니다.Actions that have a model object return type will return a 204 No Content response when returning null. 이 동작은 HttpNoContentOutputFormatter를 제거하여 삭제할 수 있습니다.This behavior can be removed by removing the HttpNoContentOutputFormatter. 다음 코드를 TextOutputFormatterHttpNoContentOutputFormatter를 제거합니다.The following code removes the TextOutputFormatter and HttpNoContentOutputFormatter.

services.AddMvc(options =>
{
    options.OutputFormatters.RemoveType<TextOutputFormatter>();
    options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
});

TextOutputFormatter가 없으면 string은 예를 들어 406 승인 금지를 반환합니다.Without the TextOutputFormatter, string return types return 406 Not Acceptable, for example. XML 포맷터가 있는 경우 TextOutputFormatter가 제거되면 string 반환 형식의 서식을 지정합니다.Note that if an XML formatter exists, it will format string return types if the TextOutputFormatter is removed.

HttpNoContentOutputFormatter가 없으면 null 개체는 구성된 포맷터를 사용하여 서식이 지정됩니다.Without the HttpNoContentOutputFormatter, null objects are formatted using the configured formatter. 예를 들어 JSON 포맷터는 null의 본문으로 응답을 반환하는 반면, XML 포맷터는 특성 xsi:nil="true" 집합으로 빈 XML 요소를 반환합니다.For example, the JSON formatter will simply return a response with a body of null, while the XML formatter will return an empty XML element with the attribute xsi:nil="true" set.

응답 형식 URL 매핑Response Format URL Mappings

클라이언트는 쿼리 문자열 또는 일부 경로와 같은 URL의 일부로, 또는 .xml이나 .json과 같은 형식별 파일 확장명을 사용하여 특정 형식을 요청할 수 있습니다.Clients can request a particular format as part of the URL, such as in the query string or part of the path, or by using a format-specific file extension such as .xml or .json. 요청 경로의 매핑은 API가 사용하는 경로에 지정해야 합니다.The mapping from request path should be specified in the route the API is using. 예:For example:

[FormatFilter]
public class ProductsController
{
    [Route("[controller]/[action]/{id}.{format?}")]
    public Product GetById(int id)

이 경로를 사용하면 요청된 형식을 선택적 파일 확장명으로 지정할 수 있습니다.This route would allow the requested format to be specified as an optional file extension. [FormatFilter] 특성은 RouteData에서 형식 값의 존재 여부를 검사하며 응답이 생성될 때 응답 형식을 적절한 포맷터에 매핑합니다.The [FormatFilter] attribute checks for the existence of the format value in the RouteData and will map the response format to the appropriate formatter when the response is created.

경로Route 포맷터Formatter
/products/GetById/5 기본 출력 포맷터The default output formatter
/products/GetById/5.json JSON 포맷터(구성된 경우)The JSON formatter (if configured)
/products/GetById/5.xml XML 포맷터(구성된 경우)The XML formatter (if configured)