Formatar dados de resposta na API Web ASP.NET CoreFormat response data in ASP.NET Core Web API

Por Steve SmithBy Steve Smith

O ASP.NET Core MVC tem suporte interno para formatação de dados de resposta, usando formatos fixos ou em resposta às especificações do cliente.ASP.NET Core MVC has built-in support for formatting response data, using fixed formats or in response to client specifications.

Exibir ou baixar código de exemplo (como baixar)View or download sample code (how to download)

Resultados da ação específicos a um formatoFormat-Specific Action Results

Alguns tipos de resultado de ação são específicos a um formato específico, como JsonResult e ContentResult.Some action result types are specific to a particular format, such as JsonResult and ContentResult. As ações podem retornar resultados específicos que são sempre formatados de determinada maneira.Actions can return specific results that are always formatted in a particular manner. Por exemplo, o retorno de um JsonResult retornará dados formatados em JSON, independentemente das preferências do cliente.For example, returning a JsonResult will return JSON-formatted data, regardless of client preferences. Da mesma forma, o retorno de um ContentResult retornará dados de cadeia de caracteres formatados como texto sem formatação (assim como o simples retorno de uma cadeia de caracteres).Likewise, returning a ContentResult will return plain-text-formatted string data (as will simply returning a string).

Observação

Uma ação não precisa retornar nenhum tipo específico; o MVC dá suporte a qualquer valor retornado de objeto.An action isn't required to return any particular type; MVC supports any object return value. Se uma ação retorna uma implementação IActionResult e o controlador herda de Controller, os desenvolvedores têm muitos métodos auxiliares correspondentes a muitas das opções.If an action returns an IActionResult implementation and the controller inherits from Controller, developers have many helper methods corresponding to many of the choices. Os resultados de ações que retornam objetos que não são tipos IActionResult serão serializados usando a implementação IOutputFormatter apropriada.Results from actions that return objects that are not IActionResult types will be serialized using the appropriate IOutputFormatter implementation.

Para retornar dados em um formato específico de um controlador que herda da classe base Controller, use o método auxiliar interno Json para retornar JSON e Content para texto sem formatação.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. O método de ação deve retornar o tipo de resultado específico (por exemplo, JsonResult) ou IActionResult.Your action method should return either the specific result type (for instance, JsonResult) or IActionResult.

Retornando dados formatados em JSON:Returning JSON-formatted data:

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

Resposta de exemplo desta ação:Sample response from this action:

Guia Rede das Ferramentas para Desenvolvedores no Microsoft Edge mostrando que o Tipo de conteúdo da resposta é application/json

Observe que o tipo de conteúdo da resposta é application/json, conforme mostrado na lista de solicitações de rede e na seção Cabeçalhos de Resposta.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. Além disso, observe a lista de opções apresentada pelo navegador (nesse caso, Microsoft Edge) no cabeçalho Accept da seção Cabeçalhos de Solicitação.Also note the list of options presented by the browser (in this case, Microsoft Edge) in the Accept header in the Request Headers section. A técnica atual é ignorar esse cabeçalho. Abaixo, abordamos como obedecê-lo.The current technique is ignoring this header; obeying it is discussed below.

Para retornar dados formatados como texto sem formatação, use ContentResult e o auxiliar Content: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.");
}

Uma resposta dessa ação:A response from this action:

Guia Rede das Ferramentas para Desenvolvedores no Microsoft Edge mostrando que o Tipo de conteúdo da resposta é text/plain

Observe, neste caso, que o Content-Type retornado é text/plain.Note in this case the Content-Type returned is text/plain. Também obtenha esse mesmo comportamento usando apenas um tipo de resposta de cadeia de caracteres: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";
}

Dica

Para ações não triviais com vários tipos de retorno ou várias opções (por exemplo, códigos de status HTTP diferentes com base no resultado das operações executadas), prefira IActionResult como o tipo de retorno.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.

Negociação de conteúdoContent Negotiation

A negociação de conteúdo (conneg de forma abreviada) ocorre quando o cliente especifica um cabeçalho Accept.Content negotiation (conneg for short) occurs when the client specifies an Accept header. O formato padrão usado pelo ASP.NET Core MVC é JSON.The default format used by ASP.NET Core MVC is JSON. A negociação de conteúdo é implementada por ObjectResult.Content negotiation is implemented by ObjectResult. Ela também foi desenvolvida com base nos resultados de ação específica de código de status retornados dos métodos auxiliares (que se baseiam em ObjectResult).It's also built into the status code specific action results returned from the helper methods (which are all based on ObjectResult). Também retorne um tipo de modelo (uma classe que você definiu como o tipo de transferência de dados) e a estrutura o encapsulará automaticamente em um ObjectResult para você.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.

O seguinte método de ação usa os métodos auxiliares Ok e NotFound: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);
}

Uma resposta formatada em JSON será retornada, a menos que outro formato tenha sido solicitado e o servidor possa retornar o formato solicitado.A JSON-formatted response will be returned unless another format was requested and the server can return the requested format. Use uma ferramenta como o Fiddler para criar uma solicitação que inclui um cabeçalho Accept e especifique outro formato.You can use a tool like Fiddler to create a request that includes an Accept header and specify another format. Nesse caso, se o servidor tiver um formatador que pode produzir uma resposta no formato solicitado, o resultado será retornado no formato preferencial do cliente.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.

Console do Fiddler mostrando uma solicitação GET criada manualmente com o valor application/xml do cabeçalho Accept

Na captura de tela acima, o Fiddler Composer foi usado para gerar uma solicitação, especificando Accept: application/xml.In the above screenshot, the Fiddler Composer has been used to generate a request, specifying Accept: application/xml. Por padrão, o ASP.NET Core MVC dá suporte apenas ao JSON e, portanto, mesmo quando outro formato é especificado, o resultado retornado ainda é formatado em JSON.By default, ASP.NET Core MVC only supports JSON, so even when another format is specified, the result returned is still JSON-formatted. Você verá como adicionar outros formatadores na próxima seção.You'll see how to add additional formatters in the next section.

As ações do controlador podem retornar POCOs (Objetos CLR Básicos); nesse caso, o ASP.NET Core MVC criará automaticamente um ObjectResult que encapsula o objeto.Controller actions can return POCOs (Plain Old CLR Objects), in which case ASP.NET Core MVC automatically creates an ObjectResult for you that wraps the object. O cliente receberá o objeto serializado formatado (o formato JSON é o padrão; você pode configurar XML ou outros formatos).The client will get the formatted serialized object (JSON format is the default; you can configure XML or other formats). Se o objeto que está sendo retornado for null, a estrutura retornará uma resposta 204 No Content.If the object being returned is null, then the framework will return a 204 No Content response.

Retornando um tipo de objeto:Returning an object type:

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

Na amostra, uma solicitação para um alias de autor válido receberá uma resposta 200 OK com os dados do autor.In the sample, a request for a valid author alias will receive a 200 OK response with the author's data. Uma solicitação para um alias inválido receberá uma resposta 204 Sem Conteúdo.A request for an invalid alias will receive a 204 No Content response. Capturas de tela mostrando a resposta nos formatos XML e JSON são mostradas abaixo.Screenshots showing the response in XML and JSON formats are shown below.

Processo de negociação de conteúdoContent Negotiation Process

A negociação de conteúdo ocorre apenas se um cabeçalho Accept é exibido na solicitação.Content negotiation only takes place if an Accept header appears in the request. Quando uma solicitação contiver um cabeçalho Accept, a estrutura enumerará os tipos de mídia no cabeçalho Accept na ordem de preferência e tentará encontrar um formatador que pode produzir uma resposta em um dos formatos especificados pelo cabeçalho 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. Caso nenhum formatador que pode atender à solicitação do cliente seja encontrado, a estrutura tentará encontrar o primeiro formatador que pode produzir uma resposta (a menos que o desenvolvedor tenha configurado a opção em MvcOptions para retornar 406 Não Aceitável).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). Se a solicitação especificar XML, mas o formatador XML não tiver sido configurado, o formatador JSON será usado.If the request specifies XML, but the XML formatter has not been configured, then the JSON formatter will be used. Geralmente, se nenhum formatador que pode fornecer o formato solicitado for configurado, o primeiro formatador que pode formatar o objeto será usado.More generally, if no formatter is configured that can provide the requested format, then the first formatter that can format the object is used. Se nenhum cabeçalho for fornecido, o primeiro formatador que pode manipular o objeto a ser retornado será usado para serializar a resposta.If no header is given, the first formatter that can handle the object to be returned will be used to serialize the response. Nesse caso, não ocorre nenhuma negociação – o servidor determina qual formato será usado.In this case, there isn't any negotiation taking place - the server is determining what format it will use.

Observação

Se o cabeçalho Accept contiver */*, o Cabeçalho será ignorado, a menos que RespectBrowserAcceptHeader seja definido como verdadeiro em MvcOptions.If the Accept header contains */*, the Header will be ignored unless RespectBrowserAcceptHeader is set to true on MvcOptions.

Navegadores e negociação de conteúdoBrowsers and Content Negotiation

Ao contrário dos clientes de API típicos, os navegadores da Web tendem a fornecer cabeçalhos Accept que incluem uma ampla variedade de formatos, incluindo caracteres curinga.Unlike typical API clients, web browsers tend to supply Accept headers that include a wide array of formats, including wildcards. Por padrão, quando a estrutura detectar que a solicitação é proveniente de um navegador, ela ignorará o cabeçalho Accept e retornará o conteúdo no formato padrão configurado do aplicativo (JSON, a menos que outro formato seja configurado).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). Isso fornece uma experiência mais consistente no uso de diferentes navegadores para consumir APIs.This provides a more consistent experience when using different browsers to consume APIs.

Se preferir que o aplicativo respeite os cabeçalhos Accept do navegador, defina isso como parte da configuração do MVC definindo RespectBrowserAcceptHeader como true no método ConfigureServices em Startup.cs.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
});

Configurando formatadoresConfiguring Formatters

Se o aplicativo precisar dar suporte a outros formatos além do padrão de JSON, adicione pacotes NuGet e configure o MVC para dar suporte a eles.If your application needs to support additional formats beyond the default of JSON, you can add NuGet packages and configure MVC to support them. Há formatadores separados para entrada e saída.There are separate formatters for input and output. Os formatadores de entrada são usados pelo Model Binding; os formatadores de saída são usados para formatar as respostas.Input formatters are used by Model Binding; output formatters are used to format responses. Também configure Formatadores Personalizados.You can also configure Custom Formatters.

Configurar formatadores com base em System.Text.JsonConfigure System.Text.Json-based formatters

Os recursos do formatadores com base em System.Text.Json podem ser configurados, usando Microsoft.AspNetCore.Mvc.MvcOptions.SerializerOptions.Features for the System.Text.Json-based formatters can be configured using Microsoft.AspNetCore.Mvc.MvcOptions.SerializerOptions.

services.AddMvc(options =>
{
    options.SerializerOptions.WriterSettings.Indented = true;
});

Adicionar suporte ao formato JSON com base em Newtonsoft.JsonAdd Newtonsoft.Json-based JSON format support

Antes do ASP.NET Core 3.0, o MVC assumia como padrão usar formatadores JSON implementados, usando o pacote Newtonsoft.Json.Prior to ASP.NET Core 3.0, MVC defaulted to using JSON formatters implemented using the Newtonsoft.Json package. No ASP.NET Core 3.0 ou posterior, os formatadores JSON padrão baseiam-se no System.Text.Json.In ASP.NET Core 3.0 or later, the default JSON formatters are based on System.Text.Json. O suporte para formatadores e recursos baseados em Newtonsoft.Json está disponível por meio da instalação do pacote NuGet Microsoft.AspNetCore.Mvc.NewtonsoftJson e da configuração dele no Startup.ConfigureServices.Support for Newtonsoft.Json-based formatters and features is available by installing the Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet package and configuring it in Startup.ConfigureServices.

services.AddMvc()
    .AddNewtonsoftJson();

Alguns recursos podem não funcionar bem com formatadores baseados em System.Text.Json e exigem uma referência aos formatadores baseados em Newtonsoft.Json para a versão do ASP.NET Core 3.0.Some features may not work well with System.Text.Json-based formatters and require a reference to the Newtonsoft.Json-based formatters for the ASP.NET Core 3.0 release. Continue a usar os formatadores baseados em Newtonsoft.Json, se seu aplicativo for o ASP.NET Core 3.0 ou posterior:Continue using the Newtonsoft.Json-based formatters if your ASP.NET Core 3.0 or later app:

  • Use os atributos Newtonsoft.Json (por exemplo, [JsonProperty] ou [JsonIgnore]), personalize as configurações de serialização ou conte com os recursos fornecidos por Newtonsoft.Json.Uses Newtonsoft.Json attributes (for example, [JsonProperty] or [JsonIgnore]), customizes the serialization settings, or relies on features that Newtonsoft.Json provides.
  • Configura Microsoft.AspNetCore.Mvc.JsonResult.SerializerSettings.Configures Microsoft.AspNetCore.Mvc.JsonResult.SerializerSettings. Antes do ASP.NET Core 3.0, JsonResult.SerializerSettings aceita uma instância de JsonSerializerSettings que é específico para Newtonsoft.Json.Prior to ASP.NET Core 3.0, JsonResult.SerializerSettings accepts an instance of JsonSerializerSettings that is specific to Newtonsoft.Json.
  • Gera documentação OpenAPI.Generates OpenAPI documentation.

Adicionar suporte ao formato XMLAdd XML format support

Para adicionar suporte à formatação XML ao ASP.NET Core 2.2 ou anterior, instale o pacote do NuGet Microsoft.AspNetCore.Mvc.Formatters.Xml.To add XML formatting support in ASP.NET Core 2.2 or earlier, install the Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet package.

Os formatadores XML implementados usando System.Xml.Serialization.XmlSerializer podem ser configurados chamando AddXmlSerializerFormatters em Startup.ConfigureServices:XML formatters implemented using System.Xml.Serialization.XmlSerializer can be configured by calling AddXmlSerializerFormatters in Startup.ConfigureServices:

services.AddMvc()
    .AddXmlSerializerFormatters();

Como alternativa, os formatadores XML implementados, usando System.Runtime.Serialization.DataContractSerializer, podem ser configurados chamando AddXmlDataContractSerializerFormatters em Startup.ConfigureServices:Alternatively, XML formatters implemented using System.Runtime.Serialization.DataContractSerializer can be configured by calling AddXmlDataContractSerializerFormatters in Startup.ConfigureServices:

services.AddMvc()
    .AddXmlDataContractSerializerFormatters();

Depois de adicionar suporte para a formatação XML, os métodos do controlador deverão retornar o formato apropriado com base no cabeçalho Accept da solicitação, como demonstra este exemplo do 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:

Console do Fiddler: a guia Bruto da solicitação mostra que o valor do cabeçalho Accept é application/xml.

Na guia Inspetores, é possível ver que a solicitação GET Bruta foi feita com um conjunto de cabeçalhos Accept: application/xml.You can see in the Inspectors tab that the Raw GET request was made with an Accept: application/xml header set. O painel de resposta mostra o cabeçalho Content-Type: application/xml e o objeto Author foi serializado em XML.The response pane shows the Content-Type: application/xml header, and the Author object has been serialized to XML.

Use a guia Criador para modificar a solicitação para especificar application/json no cabeçalho Accept.Use the Composer tab to modify the request to specify application/json in the Accept header. Execute a solicitação e a resposta será formatada como JSON:Execute the request, and the response will be formatted as JSON:

Console do Fiddler: a guia Bruto da solicitação mostra que o valor do cabeçalho Accept é application/json.

Nessa captura de tela, é possível ver a solicitação definir um cabeçalho Accept: application/json e a resposta especificar o mesmo como seu 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. O objeto Author é mostrado no corpo da resposta, em formato JSON.The Author object is shown in the body of the response, in JSON format.

Forçando um formato específicoForcing a Particular Format

Caso deseje restringir os formatos de resposta de uma ação específica, aplique o filtro [Produces].If you would like to restrict the response formats for a specific action you can, you can apply the [Produces] filter. O filtro [Produces] especifica os formatos de resposta de uma ação específica (ou o controlador).The [Produces] filter specifies the response formats for a specific action (or controller). Como a maioria dos Filtros, isso pode ser aplicado no escopo da ação, do controlador ou global.Like most Filters, this can be applied at the action, controller, or global scope.

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

O filtro [Produces] forçará todas as ações em AuthorsController a retornar respostas formatadas em JSON, mesmo se outros formatadores foram configurados para o aplicativo e o cliente forneceu um cabeçalho Accept solicitando outro formato disponível.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. Consulte Filtros para saber mais, incluindo como aplicar filtros globalmente.See Filters to learn more, including how to apply filters globally.

Formatadores de casos especiaisSpecial Case Formatters

Alguns casos especiais são implementados com formatadores internos.Some special cases are implemented using built-in formatters. Por padrão, os tipos de retorno string serão formatados como text/plain (text/html, se solicitado por meio do cabeçalho Accept).By default, string return types will be formatted as text/plain (text/html if requested via Accept header). Esse comportamento pode ser removido com a remoção do TextOutputFormatter.This behavior can be removed by removing the TextOutputFormatter. Remova formatadores no método Configure em Startup.cs (mostrado abaixo).You remove formatters in the Configure method in Startup.cs (shown below). Ações que têm um tipo de retorno de objeto de modelo retornarão uma resposta 204 Sem Conteúdo ao retornar null.Actions that have a model object return type will return a 204 No Content response when returning null. Esse comportamento pode ser removido com a remoção do HttpNoContentOutputFormatter.This behavior can be removed by removing the HttpNoContentOutputFormatter. O código a seguir remove o TextOutputFormatter e o HttpNoContentOutputFormatter.The following code removes the TextOutputFormatter and HttpNoContentOutputFormatter.

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

Sem o TextOutputFormatter, os tipos de retorno string retornam 406 Não Aceitável, por exemplo.Without the TextOutputFormatter, string return types return 406 Not Acceptable, for example. Observe que se um formatador XML existir, ele formatará tipos de retorno string se o TextOutputFormatter for removido.Note that if an XML formatter exists, it will format string return types if the TextOutputFormatter is removed.

Sem o HttpNoContentOutputFormatter, os objetos nulos são formatados com o formatador configurado.Without the HttpNoContentOutputFormatter, null objects are formatted using the configured formatter. Por exemplo, o formatador JSON apenas retornará uma resposta com um corpo null, enquanto o formatador XML retornará um elemento XML vazio com o atributo xsi:nil="true" definido.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.

Mapeamentos de URL do formato da respostaResponse Format URL Mappings

Os clientes podem solicitar um formato específico como parte da URL, como na cadeia de caracteres de consulta ou parte do caminho, ou usando uma extensão de arquivo específica a um formato, como .xml ou .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. O mapeamento do caminho da solicitação deve ser especificado na rota que está sendo usada pela API.The mapping from request path should be specified in the route the API is using. Por exemplo:For example:

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

Essa rota permitirá que o formato solicitado seja especificado como uma extensão de arquivo opcional.This route would allow the requested format to be specified as an optional file extension. O atributo [FormatFilter] verifica a existência do valor de formato no RouteData e mapeará o formato da resposta para o formatador adequado quando a resposta for criada.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.

RotaRoute FormatadorFormatter
/products/GetById/5 O formatador de saída padrãoThe default output formatter
/products/GetById/5.json O formatador JSON (se configurado)The JSON formatter (if configured)
/products/GetById/5.xml O formatador XML (se configurado)The XML formatter (if configured)