Formatar dados de resposta na API Web ASP.NET Core

ASP.NET Core MVC dá suporte à formatação de dados de resposta, usando formatos especificados ou em resposta à solicitação de um cliente.

Resultados de ação específicos do formato

Alguns tipos de resultado de ação são específicos a um formato específico, como JsonResult e ContentResult. As ações podem retornar resultados que sempre usam um formato especificado, ignorando a solicitação de um cliente para um formato diferente. Por exemplo, retornar JsonResult retorna JSdados formatados em ON e retornar ContentResult retorna dados de cadeia de caracteres formatados em texto sem formatação.

Uma ação não é necessária para retornar qualquer tipo específico. ASP.NET Core dá suporte a qualquer valor de retorno de objeto. Os resultados de ações que retornam objetos que não IActionResult são tipos são serializados usando a implementação apropriada IOutputFormatter . Para obter mais informações, consulte Os tipos de retorno da ação do controlador em ASP.NET Core API Web.

Por padrão, o método ControllerBase.Ok auxiliar interno retorna JSdados formatados em ON:

[HttpGet]
public IActionResult Get() =>
    Ok(_todoItemStore.GetList());

O código de exemplo retorna uma lista de itens de todo. Usando as ferramentas de desenvolvedor do navegador F12 ou o Postman com as exibições de código anteriores:

  • O cabeçalho de resposta que contém o tipo de conteúdo:application/json; charset=utf-8.
  • Os cabeçalhos de solicitação. Por exemplo, o Accept cabeçalho. O Accept cabeçalho é ignorado pelo código anterior.

Para retornar dados formatados como texto sem formatação, use ContentResult e o auxiliar Content:

[HttpGet("Version")]
public ContentResult GetVersion() =>
    Content("v1.0.0");

No código anterior, o Content-Type retornado é text/plain.

Para ações com vários tipos de retorno, retorne IActionResult. Por exemplo, ao retornar diferentes códigos de status HTTP com base no resultado da operação.

Negociação de conteúdo

A negociação de conteúdo ocorre quando o cliente especifica um cabeçalho Accept. O formato padrão usado pelo ASP.NET Core é JSON. A negociação de conteúdo é:

  • Implementado por ObjectResult.
  • Integrados aos resultados de ação específicos do código de status retornados dos métodos auxiliares. Os métodos auxiliares de resultados da ação são baseados em ObjectResult.

Quando um tipo de modelo é retornado, o tipo de retorno é ObjectResult.

O seguinte método de ação usa os métodos auxiliares Ok e NotFound:

[HttpGet("{id:long}")]
public IActionResult GetById(long id)
{
    var todo = _todoItemStore.GetById(id);

    if (todo is null)
    {
        return NotFound();
    }

    return Ok(todo);
}

Por padrão, ASP.NET Core dá suporte aos seguintes tipos de mídia:

  • application/json
  • text/json
  • text/plain

Ferramentas como Fiddler ou Postman podem definir o cabeçalho da Accept solicitação para especificar o formato de retorno. Quando o Accept cabeçalho contém um tipo compatível com o servidor, esse tipo é retornado. A próxima seção mostra como adicionar formatores adicionais.

As ações do controlador podem retornar POCOs (objetos CLR antigos simples). Quando um POCO é retornado, o runtime cria automaticamente um ObjectResult que encapsula o objeto. O cliente obtém o objeto serializado formatado. Se o objeto que está sendo retornado for null, uma 204 No Content resposta será retornada.

O exemplo a seguir retorna um tipo de objeto:

[HttpGet("{id:long}")]
public TodoItem? GetById(long id) =>
    _todoItemStore.GetById(id);

No código anterior, uma solicitação para um item todo válido retorna uma 200 OK resposta. Uma solicitação para um item todo inválido retorna uma 204 No Content resposta.

O cabeçalho Accept

A negociação de conteúdo ocorre quando um Accept cabeçalho aparece na solicitação. Quando uma solicitação contém um cabeçalho de aceitação, ASP.NET Core:

  • Enumera os tipos de mídia no cabeçalho de aceitação na ordem de preferência.
  • Tenta encontrar um formatador que possa produzir uma resposta em um dos formatos especificados.

Se nenhum formatador for encontrado que possa atender à solicitação do cliente, ASP.NET Core:

Se nenhum formatador estiver configurado para o formato solicitado, o primeiro formatador que pode formatar o objeto será usado. Se nenhum Accept cabeçalho for exibido na solicitação:

  • O primeiro formatador que pode manipular o objeto é usado para serializar a resposta.
  • Não há nenhuma negociação acontecendo. O servidor está determinando qual formato retornar.

Se o cabeçalho Accept contiver */*, o cabeçalho será ignorado, a menos que RespectBrowserAcceptHeader seja definido como true em MvcOptions.

Navegadores e negociação de conteúdo

Ao contrário dos clientes típicos da API, os navegadores da Web fornecem Accept cabeçalhos. Navegadores da Web especificam muitos formatos, incluindo curingas. Por padrão, quando a estrutura detecta que a solicitação vem de um navegador:

  • O Accept cabeçalho é ignorado.
  • O conteúdo é retornado em JSON, a menos que esteja configurado de outra forma.

Essa abordagem fornece uma experiência mais consistente entre navegadores ao consumir APIs.

Para configurar um aplicativo para respeitar os cabeçalhos de aceitação do navegador, defina a RespectBrowserAcceptHeader propriedade como true:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    options.RespectBrowserAcceptHeader = true;
});

Configurar formatadores

Os aplicativos que precisam dar suporte a formatos extras podem adicionar os pacotes NuGet apropriados e configurar o suporte. Há formatadores separados para entrada e saída. Os formatadores de entrada são usados pela Associação de Modelos. Os formatadores de saída são usados para formatar respostas. Para obter informações sobre como criar um formatador personalizado, consulte Formatters Personalizados.

Adicionar suporte ao formato XML

Para configurar os formatadores XML implementados usando XmlSerializer, chame AddXmlSerializerFormatters:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddXmlSerializerFormatters();

Ao usar o código anterior, os métodos de controlador retornam o formato apropriado com base no cabeçalho da Accept solicitação.

Configurar System.Text.Jsonformatadores baseados

Para configurar recursos para os System.Text.Jsonformatadores baseados, use Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. O código realçado a seguir configura a formatação PascalCase em vez da formatação camelCase padrão:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNamingPolicy = null;
    });

O seguinte método de ação chama ControllerBase.Problem para criar uma ProblemDetails resposta:

[HttpGet("Error")]
public IActionResult GetError() =>
    Problem("Something went wrong.");

Uma ProblemDetails resposta é sempre camelCase, mesmo quando o aplicativo define o formato como PascalCase. ProblemDetails segue RFC 7807, que especifica minúsculas.

Para configurar opções de serialização de saída para ações específicas, use JsonResult. Por exemplo:

[HttpGet]
public IActionResult Get() =>
    new JsonResult(
        _todoItemStore.GetList(),
        new JsonSerializerOptions
        {
            PropertyNamingPolicy = null
        });

Adicionar Newtonsoft.Jsonsuporte ao formato ON baseado em JS

Os formatadores ON padrão JSusam System.Text.Json. Para usar os Newtonsoft.Jsonformatadores baseados, instale o pacote NuGet e configure-o Microsoft.AspNetCore.Mvc.NewtonsoftJson em Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddNewtonsoftJson();

No código anterior, a chamada para AddNewtonsoftJson configurar os seguintes recursos de API Web, MVC e Razor Páginas a serem usados Newtonsoft.Json:

Alguns recursos podem não funcionar bem com System.Text.Jsonformatadores baseados e exigem uma referência aos Newtonsoft.Jsonformatadores baseados. Continue usando os Newtonsoft.Jsonformatadores baseados quando o aplicativo:

  • Usa atributos Newtonsoft.Json . Por exemplo, [JsonProperty] ou [JsonIgnore].
  • Personaliza as configurações de serialização.
  • Depende dos recursos que Newtonsoft.Json fornecem.

Para configurar recursos para os Newtonsoft.Jsonformatadores baseados, use SerializerSettings:

builder.Services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.ContractResolver = new DefaultContractResolver();
    });

Para configurar opções de serialização de saída para ações específicas, use JsonResult. Por exemplo:

[HttpGet]
public IActionResult GetNewtonsoftJson() =>
    new JsonResult(
        _todoItemStore.GetList(),
        new JsonSerializerSettings
        {
            ContractResolver = new DefaultContractResolver()
        });

Especificar um formato

Para restringir os formatos de resposta, aplique o [Produces] filtro. Como a maioria dos Filtros, [Produces] pode ser aplicado na ação, no controlador ou no escopo global:

[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class TodoItemsController : ControllerBase

O filtro anterior [Produces] :

  • Força todas as ações dentro do controlador a retornar JSrespostas formatadas em ON para POCOs (Objetos CLR Antigos Simples) ou ObjectResult seus tipos derivados.
  • Retornar JSrespostas formatadas em ON mesmo se outros formatores estiverem configurados e o cliente especificar um formato diferente.

Para obter mais informações, consulte Filtros.

Formatores de casos especiais

Alguns casos especiais são implementados com formatadores internos. Por padrão, string os tipos de retorno são formatados como texto/sem formatação (texto/html , se solicitado por meio do Accept cabeçalho). Esse comportamento pode ser excluído removendo o StringOutputFormatter. Os formatadores são removidos em Program.cs. Ações que têm um tipo de retorno de objeto de modelo retornam 204 No Content ao retornar null. Esse comportamento pode ser excluído removendo o HttpNoContentOutputFormatter. O código a seguir remove o StringOutputFormatter e o HttpNoContentOutputFormatter.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    // using Microsoft.AspNetCore.Mvc.Formatters;
    options.OutputFormatters.RemoveType<StringOutputFormatter>();
    options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
});

Sem os StringOutputFormattertipos de retorno dos formatos string de formatador ON internosJS. Se o formatador ON interno JSfor removido e um formatador XML estiver disponível, os formatos string de formatador XML retornarão tipos. Caso contrário, string os tipos de retorno retornarão 406 Not Acceptable.

Sem o HttpNoContentOutputFormatter, os objetos nulos são formatados com o formatador configurado. Por exemplo:

  • O JSformatador ON retorna uma resposta com um corpo de null.
  • O formatador XML retorna um elemento XML vazio com o conjunto de atributos xsi:nil="true" .

Mapeamentos de URL de formato de resposta

Os clientes podem solicitar um formato específico como parte da URL, por exemplo:

  • Na cadeia de caracteres de consulta ou parte do caminho.
  • Usando uma extensão de arquivo específica de formato, como .xml ou .json.

O mapeamento do caminho da solicitação deve ser especificado na rota que está sendo usada pela API. Por exemplo:

[ApiController]
[Route("api/[controller]")]
[FormatFilter]
public class TodoItemsController : ControllerBase
{
    private readonly TodoItemStore _todoItemStore;

    public TodoItemsController(TodoItemStore todoItemStore) =>
        _todoItemStore = todoItemStore;

    [HttpGet("{id:long}.{format?}")]
    public TodoItem? GetById(long id) =>
        _todoItemStore.GetById(id);

A rota anterior permite que o formato solicitado seja especificado usando uma extensão de arquivo opcional. O [FormatFilter] atributo verifica a existência do valor de formato no RouteData formato e mapeia o formato de resposta para o formatador apropriado quando a resposta é criada.

Rota Formatador
/api/todoitems/5 O formatador de saída padrão
/api/todoitems/5.json O JSformatador ON (se configurado)
/api/todoitems/5.xml O formatador XML (se configurado)

Desserialização polimórfica

Os recursos internos fornecem um intervalo limitado de serialização polimórfica, mas nenhum suporte para desserialização. A desserialização requer um conversor personalizado. Consulte a desserialização polimórfica para obter uma amostra completa de desserialização polimórfica.

Recursos adicionais

ASP.NET Core MVC tem suporte para formatação de dados de resposta. Os dados de resposta podem ser formatados usando formatos específicos ou em resposta ao formato solicitado pelo cliente.

Exibir ou baixar código de exemplo (como baixar)

Resultados de ação específicos do formato

Alguns tipos de resultado de ação são específicos a um formato específico, como JsonResult e ContentResult. As ações podem retornar resultados formatados em um formato específico, independentemente das preferências do cliente. Por exemplo, retornar JsonResult retorna JSdados formatados como ON. Retornando ContentResult ou uma cadeia de caracteres retorna dados de cadeia de caracteres formatada em texto sem formatação.

Uma ação não é necessária para retornar nenhum tipo específico. ASP.NET Core dá suporte a qualquer valor de retorno de objeto. Os resultados de ações que retornam objetos que não IActionResult são tipos são serializados usando a implementação apropriada IOutputFormatter . Para obter mais informações, consulte Tipos de retorno de ação do controlador em ASP.NET Core API Web.

O método Ok auxiliar interno retorna JSdados formatados em ON:

// GET: api/authors
[HttpGet]
public ActionResult Get()
{
    return Ok(_authors.List());
}

O download de exemplo retorna a lista de autores. Usando as ferramentas de desenvolvedor do navegador F12 ou o Postman com o código anterior:

  • O cabeçalho de resposta que contém o tipo de conteúdo:application/json; charset=utf-8 é exibido.
  • Os cabeçalhos de solicitação são exibidos. Por exemplo, o Accept cabeçalho. O Accept cabeçalho é ignorado pelo código anterior.

Para retornar dados formatados como texto sem formatação, use ContentResult e o auxiliar Content:

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

No código anterior, o Content-Type retornado é text/plain. Retornando uma cadeia de text/plaincaracteres Content-Type de:

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

Para ações com vários tipos de retorno, retorne IActionResult. Por exemplo, retornando códigos de status HTTP diferentes com base no resultado das operações executadas.

Negociação de conteúdo

A negociação de conteúdo ocorre quando o cliente especifica um cabeçalho Accept. O formato padrão usado por ASP.NET Core é JSON. A negociação de conteúdo é:

  • Implementado por ObjectResult.
  • Integrados aos resultados de ação específicos do código de status retornados dos métodos auxiliares. Os métodos auxiliares de resultados da ação são baseados em ObjectResult.

Quando um tipo de modelo é retornado, o tipo de retorno é ObjectResult.

O seguinte método de ação usa os métodos auxiliares Ok e NotFound:

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

Por padrão, ASP.NET Core dá suporte application/jsona text/jsontipos de mídia e text/plain de mídia. Ferramentas como Fiddler ou Postman podem definir o cabeçalho da Accept solicitação para especificar o formato de retorno. Quando o Accept cabeçalho contém um tipo compatível com o servidor, esse tipo é retornado. A próxima seção mostra como adicionar formatores adicionais.

As ações do controlador podem retornar POCOs (Objetos CLR Antigos Simples). Quando um POCO é retornado, o runtime cria automaticamente um ObjectResult que encapsula o objeto. O cliente obtém o objeto serializado formatado. Se o objeto que está sendo retornado for null, uma 204 No Content resposta será retornada.

Retornando um tipo de objeto:

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

No código anterior, uma solicitação para um alias de autor válido retorna uma 200 OK resposta com os dados do autor. Uma solicitação de um alias inválido retorna uma 204 No Content resposta.

O cabeçalho Accept

A negociação de conteúdo ocorre quando um Accept cabeçalho aparece na solicitação. Quando uma solicitação contém um cabeçalho de aceitação, ASP.NET Core:

  • Enumera os tipos de mídia no cabeçalho de aceitação na ordem de preferência.
  • Tenta encontrar um formatador que pode produzir uma resposta em um dos formatos especificados.

Se nenhum formatador for encontrado que possa atender à solicitação do cliente, ASP.NET Core:

Se nenhum formatador estiver configurado para o formato solicitado, o primeiro formatador que pode formatar o objeto será usado. Se nenhum Accept cabeçalho for exibido na solicitação:

  • O primeiro formatador que pode manipular o objeto é usado para serializar a resposta.
  • Não há nenhuma negociação acontecendo. O servidor está determinando qual formato retornar.

Se o cabeçalho Aceitar contiver*/*, o cabeçalho será ignorado, a menos que RespectBrowserAcceptHeader seja definido como true.MvcOptions

Navegadores e negociação de conteúdo

Ao contrário dos clientes de API típicos, os navegadores da Web fornecem Accept cabeçalhos. Navegadores da Web especificam muitos formatos, incluindo caracteres curinga. Por padrão, quando a estrutura detecta que a solicitação vem de um navegador:

  • O Accept cabeçalho é ignorado.
  • O conteúdo é retornado em JSON, a menos que seja configurado de outra forma.

Essa abordagem fornece uma experiência mais consistente entre navegadores ao consumir APIs.

Para configurar um aplicativo para honrar os cabeçalhos de aceitação do navegador, defina RespectBrowserAcceptHeader como true:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(options =>
    {
        options.RespectBrowserAcceptHeader = true; // false by default
    });
}

Configurar formatadores

Aplicativos que precisam dar suporte a formatos adicionais podem adicionar os pacotes NuGet apropriados e configurar o suporte. Há formatadores separados para entrada e saída. Os formatadores de entrada são usados pela Associação de Modelo. Os formatadores de saída são usados para formatar respostas. Para obter informações sobre como criar um formatador personalizado, consulte Formatores Personalizados.

Adicionar suporte ao formato XML

Os formatadores XML implementados usando XmlSerializer são configurados chamando AddXmlSerializerFormatters:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
        .AddXmlSerializerFormatters();
}

O código anterior serializa os resultados usando XmlSerializer.

Ao usar o código anterior, os métodos do controlador retornam o formato apropriado com base no cabeçalho da Accept solicitação.

Configurar System.Text.Json formatadores baseados

Os recursos para os System.Text.Json formatadores baseados podem ser configurados usando Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. A formatação padrão é camelCase. O código realçado a seguir define a formatação PascalCase:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
        .AddJsonOptions(options =>
            options.JsonSerializerOptions.PropertyNamingPolicy = null);
}

O método de ação a seguir chama ControllerBase.Problem para criar uma ProblemDetails resposta:

[HttpGet("error")]
public IActionResult GetError()
{
    return Problem("Something went wrong!");
}

Com o código anterior:

  • https://localhost:5001/WeatherForecast/temperature retorna PascalCase.
  • https://localhost:5001/WeatherForecast/error retorna camelCase. A resposta de erro é sempre camelCase, mesmo quando o aplicativo define o formato como PascalCase. ProblemDetails segue RFC 7807, que especifica maiúsculas e minúsculas

O código a seguir define PascalCase e adiciona um conversor personalizado:

services.AddControllers().AddJsonOptions(options =>
{
    // Use the default property (Pascal) casing.
    options.JsonSerializerOptions.PropertyNamingPolicy = null;

    // Configure a custom converter.
    options.JsonSerializerOptions.Converters.Add(new MyCustomJsonConverter());
});

As opções de serialização de saída, por ação, podem ser configuradas usando JsonResult. Por exemplo:

public IActionResult Get()
{
    return Json(model, new JsonSerializerOptions
    {
        WriteIndented = true,
    });
}

Adicionar suporte ao formato ON baseado em JSNewtonsoft.Json

Os formatadores ON padrão JSsão baseados em System.Text.Json. O suporte para Newtonsoft.Json formatores e recursos baseados está disponível instalando o pacote NuGet e configurando-o Microsoft.AspNetCore.Mvc.NewtonsoftJson em Startup.ConfigureServices.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
        .AddNewtonsoftJson();
}

No código anterior, a chamada para AddNewtonsoftJson configurar os seguintes recursos de API Web, MVC e Razor Páginas a serem usados Newtonsoft.Json:

Alguns recursos podem não funcionar bem com System.Text.Jsonformatadores baseados e exigem uma referência aos Newtonsoft.Jsonformatadores baseados. Continue usando os Newtonsoft.Jsonformatadores baseados quando o aplicativo:

  • Usa atributos Newtonsoft.Json . Por exemplo, [JsonProperty] ou [JsonIgnore].
  • Personaliza as configurações de serialização.
  • Depende dos recursos que Newtonsoft.Json fornecem.

Os recursos para os Newtonsoft.Jsonformatadores baseados podem ser configurados usando Microsoft.AspNetCore.Mvc.MvcNewtonsoftJsonOptions.SerializerSettings:

services.AddControllers().AddNewtonsoftJson(options =>
{
    // Use the default property (Pascal) casing
    options.SerializerSettings.ContractResolver = new DefaultContractResolver();

    // Configure a custom converter
    options.SerializerSettings.Converters.Add(new MyCustomJsonConverter());
});

As opções de serialização de saída, por ação, podem ser configuradas usando JsonResult. Por exemplo:

public IActionResult Get()
{
    return Json(model, new JsonSerializerSettings
    {
        Formatting = Formatting.Indented,
    });
}

Especificar um formato

Para restringir os formatos de resposta, aplique o [Produces] filtro. Como a maioria dos Filtros, [Produces] pode ser aplicado na ação, no controlador ou no escopo global:

[ApiController]
[Route("[controller]")]
[Produces("application/json")]
public class WeatherForecastController : ControllerBase
{

O filtro anterior [Produces] :

  • Força todas as ações dentro do controlador a retornar JSrespostas formatadas em ON para POCOs (Objetos CLR Antigos Simples) ou ObjectResult seus tipos derivados.
  • Se outros formatadores estiverem configurados e o cliente especificar um formato diferente, JSON será retornado.

Para obter mais informações, consulte Filtros.

Formatores de casos especiais

Alguns casos especiais são implementados com formatadores internos. Por padrão, string os tipos de retorno são formatados como texto/sem formatação (texto/html , se solicitado por meio do Accept cabeçalho). Esse comportamento pode ser excluído removendo o StringOutputFormatter. Os formatadores são removidos no ConfigureServices método. Ações que têm um tipo de retorno de objeto de modelo retornam 204 No Content ao retornar null. Esse comportamento pode ser excluído removendo o HttpNoContentOutputFormatter. O código a seguir remove o StringOutputFormatter e o HttpNoContentOutputFormatter.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(options =>
    {
        // requires using Microsoft.AspNetCore.Mvc.Formatters;
        options.OutputFormatters.RemoveType<StringOutputFormatter>();
        options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
    });
}

Sem os StringOutputFormattertipos de retorno dos formatos string de formatador ON internosJS. Se o formatador ON interno JSfor removido e um formatador XML estiver disponível, os formatos string de formatador XML retornarão tipos. Caso contrário, string os tipos de retorno retornarão 406 Not Acceptable.

Sem o HttpNoContentOutputFormatter, os objetos nulos são formatados com o formatador configurado. Por exemplo:

  • O JSformatador ON retorna uma resposta com um corpo de null.
  • O formatador XML retorna um elemento XML vazio com o conjunto de atributos xsi:nil="true" .

Mapeamentos de URL de formato de resposta

Os clientes podem solicitar um formato específico como parte da URL, por exemplo:

  • Na cadeia de caracteres de consulta ou parte do caminho.
  • Usando uma extensão de arquivo específica de formato, como .xml ou .json.

O mapeamento do caminho da solicitação deve ser especificado na rota que está sendo usada pela API. Por exemplo:

[Route("api/[controller]")]
[ApiController]
[FormatFilter]
public class ProductsController : ControllerBase
{
    [HttpGet("{id}.{format?}")]
    public Product Get(int id)
    {

A rota anterior permite que o formato solicitado seja especificado como uma extensão de arquivo opcional. O [FormatFilter] atributo verifica a existência do valor de formato no RouteData formato e mapeia o formato de resposta para o formatador apropriado quando a resposta é criada.

Rota Formatador
/api/products/5 O formatador de saída padrão
/api/products/5.json O JSformatador ON (se configurado)
/api/products/5.xml O formatador XML (se configurado)

ASP.NET Core MVC dá suporte à formatação de dados de resposta, usando formatos especificados ou em resposta à solicitação de um cliente.

Resultados de ação específicos do formato

Alguns tipos de resultado de ação são específicos a um formato específico, como JsonResult e ContentResult. As ações podem retornar resultados que sempre usam um formato especificado, ignorando a solicitação de um cliente para um formato diferente. Por exemplo, retornar JsonResult retorna JSdados formatados em ON e retornar ContentResult retorna dados de cadeia de caracteres formatadas em texto sem formatação.

Uma ação não é necessária para retornar nenhum tipo específico. ASP.NET Core dá suporte a qualquer valor de retorno de objeto. Os resultados de ações que retornam objetos que não IActionResult são tipos são serializados usando a implementação apropriada IOutputFormatter . Para obter mais informações, consulte Tipos de retorno de ação do controlador em ASP.NET Core API Web.

Por padrão, o método ControllerBase.Ok auxiliar interno retorna JSdados formatados em ON:

[HttpGet]
public IActionResult Get()
    => Ok(_todoItemStore.GetList());

O código de exemplo retorna uma lista de itens de todo. Usar as ferramentas de desenvolvedor do navegador F12 ou o Postman com o código anterior é exibido:

  • O cabeçalho de resposta que contém o tipo de conteúdo:application/json; charset=utf-8.
  • Os cabeçalhos de solicitação. Por exemplo, o Accept cabeçalho. O Accept cabeçalho é ignorado pelo código anterior.

Para retornar dados formatados como texto sem formatação, use ContentResult e o auxiliar Content:

[HttpGet("Version")]
public ContentResult GetVersion()
    => Content("v1.0.0");

No código anterior, o Content-Type retornado é text/plain.

Para ações com vários tipos de retorno, retorne IActionResult. Por exemplo, ao retornar diferentes códigos de status HTTP com base no resultado da operação.

Negociação de conteúdo

A negociação de conteúdo ocorre quando o cliente especifica um cabeçalho Accept. O formato padrão usado pelo ASP.NET Core é JSON. A negociação de conteúdo é:

  • Implementado por ObjectResult.
  • Integrados aos resultados de ação específicos do código de status retornados dos métodos auxiliares. Os métodos auxiliares de resultados da ação são baseados em ObjectResult.

Quando um tipo de modelo é retornado, o tipo de retorno é ObjectResult.

O seguinte método de ação usa os métodos auxiliares Ok e NotFound:

[HttpGet("{id:long}")]
public IActionResult GetById(long id)
{
    var todo = _todoItemStore.GetById(id);

    if (todo is null)
    {
        return NotFound();
    }

    return Ok(todo);
}

Por padrão, ASP.NET Core dá suporte aos seguintes tipos de mídia:

  • application/json
  • text/json
  • text/plain

Ferramentas como Fiddler ou Postman podem definir o cabeçalho da Accept solicitação para especificar o formato de retorno. Quando o Accept cabeçalho contém um tipo compatível com o servidor, esse tipo é retornado. A próxima seção mostra como adicionar formatores adicionais.

As ações do controlador podem retornar POCOs (objetos CLR antigos simples). Quando um POCO é retornado, o runtime cria automaticamente um ObjectResult que encapsula o objeto. O cliente obtém o objeto serializado formatado. Se o objeto que está sendo retornado for null, uma 204 No Content resposta será retornada.

O exemplo a seguir retorna um tipo de objeto:

[HttpGet("{id:long}")]
public TodoItem? GetById(long id)
    => _todoItemStore.GetById(id);

No código anterior, uma solicitação para um item todo válido retorna uma 200 OK resposta. Uma solicitação para um item todo inválido retorna uma 204 No Content resposta.

O cabeçalho Accept

A negociação de conteúdo ocorre quando um Accept cabeçalho aparece na solicitação. Quando uma solicitação contém um cabeçalho de aceitação, ASP.NET Core:

  • Enumera os tipos de mídia no cabeçalho de aceitação na ordem de preferência.
  • Tenta encontrar um formatador que possa produzir uma resposta em um dos formatos especificados.

Se nenhum formatador for encontrado que possa atender à solicitação do cliente, ASP.NET Core:

Se nenhum formatador estiver configurado para o formato solicitado, o primeiro formatador que pode formatar o objeto será usado. Se nenhum Accept cabeçalho for exibido na solicitação:

  • O primeiro formatador que pode manipular o objeto é usado para serializar a resposta.
  • Não há nenhuma negociação acontecendo. O servidor está determinando qual formato retornar.

Se o cabeçalho Accept contiver */*, o cabeçalho será ignorado, a menos que RespectBrowserAcceptHeader seja definido como true em MvcOptions.

Navegadores e negociação de conteúdo

Ao contrário dos clientes típicos da API, os navegadores da Web fornecem Accept cabeçalhos. Navegadores da Web especificam muitos formatos, incluindo curingas. Por padrão, quando a estrutura detecta que a solicitação vem de um navegador:

  • O Accept cabeçalho é ignorado.
  • O conteúdo é retornado em JSON, a menos que esteja configurado de outra forma.

Essa abordagem fornece uma experiência mais consistente entre navegadores ao consumir APIs.

Para configurar um aplicativo para respeitar os cabeçalhos de aceitação do navegador, defina a RespectBrowserAcceptHeader propriedade como true:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    options.RespectBrowserAcceptHeader = true;
});

Configurar formatadores

Os aplicativos que precisam dar suporte a formatos extras podem adicionar os pacotes NuGet apropriados e configurar o suporte. Há formatadores separados para entrada e saída. Os formatadores de entrada são usados pela Associação de Modelos. Os formatadores de saída são usados para formatar respostas. Para obter informações sobre como criar um formatador personalizado, consulte Formatters Personalizados.

Adicionar suporte ao formato XML

Para configurar os formatadores XML implementados usando XmlSerializer, chame AddXmlSerializerFormatters:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddXmlSerializerFormatters();

Ao usar o código anterior, os métodos de controlador retornam o formato apropriado com base no cabeçalho da Accept solicitação.

Configurar System.Text.Jsonformatadores baseados

Para configurar recursos para os System.Text.Jsonformatadores baseados, use Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. O código realçado a seguir configura a formatação PascalCase em vez da formatação camelCase padrão:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNamingPolicy = null;
    });

Para configurar opções de serialização de saída para ações específicas, use JsonResult. Por exemplo:

[HttpGet]
public IActionResult Get() 
    => new JsonResult(
        _todoItemStore.GetList(),
        new JsonSerializerOptions { PropertyNamingPolicy = null });

Adicionar Newtonsoft.Jsonsuporte ao formato ON baseado em JS

Os formatadores ON padrão JSusam System.Text.Json. Para usar os Newtonsoft.Jsonformatadores baseados, instale o pacote NuGet e configure-o Microsoft.AspNetCore.Mvc.NewtonsoftJson em Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddNewtonsoftJson();

No código anterior, a chamada para AddNewtonsoftJson configurar os seguintes recursos de API Web, MVC e Razor Páginas a serem usados Newtonsoft.Json:

Alguns recursos podem não funcionar bem com System.Text.Jsonformatadores baseados e exigem uma referência aos Newtonsoft.Jsonformatadores baseados. Continue usando os Newtonsoft.Jsonformatadores baseados quando o aplicativo:

  • Usa atributos Newtonsoft.Json . Por exemplo, [JsonProperty] ou [JsonIgnore].
  • Personaliza as configurações de serialização.
  • Depende dos recursos que Newtonsoft.Json fornecem.

Para configurar recursos para os Newtonsoft.Jsonformatadores baseados, use SerializerSettings:

builder.Services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.ContractResolver = new DefaultContractResolver();
    });

Para configurar opções de serialização de saída para ações específicas, use JsonResult. Por exemplo:

[HttpGet]
public IActionResult GetNewtonsoftJson()
    => new JsonResult(
        _todoItemStore.GetList(),
        new JsonSerializerSettings { ContractResolver = new DefaultContractResolver() });

Formatar ProblemDetails e ValidationProblemDetails respostas

O seguinte método de ação chama ControllerBase.Problem para criar uma ProblemDetails resposta:

[HttpGet("Error")]
public IActionResult GetError()
    => Problem("Something went wrong.");

Uma ProblemDetails resposta é sempre camelCase, mesmo quando o aplicativo define o formato como PascalCase. ProblemDetails segue RFC 7807, que especifica minúsculas.

Quando o [ApiController] atributo é aplicado a uma classe de controlador, o controlador cria uma ValidationProblemDetails resposta quando a Validação de Modelo falha. Essa resposta inclui um dicionário que usa os nomes de propriedade do modelo como chaves de erro, inalterados. Por exemplo, o seguinte modelo inclui uma única propriedade que requer validação:

public class SampleModel
{
    [Range(1, 10)]
    public int Value { get; set; }
}

Por padrão, a ValidationProblemDetails resposta retornada quando a Value propriedade é inválida usa uma chave de erro, Valueconforme mostrado no exemplo a seguir:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-00000000000000000000000000000000-000000000000000-00",
  "errors": {
    "Value": [
      "The field Value must be between 1 and 10."
    ]
  }
}

Para formatar os nomes de propriedade usados como chaves de IMetadataDetailsProvider erro, adicione uma implementação à MvcOptions.ModelMetadataDetailsProviders coleção. O exemplo a seguir adiciona uma System.Text.Jsonimplementação baseada, SystemTextJsonValidationMetadataProviderque formata nomes de propriedades como camelCase por padrão:

builder.Services.AddControllers();

builder.Services.Configure<MvcOptions>(options =>
{
    options.ModelMetadataDetailsProviders.Add(
        new SystemTextJsonValidationMetadataProvider());
});

SystemTextJsonValidationMetadataProvider também aceita uma implementação de JsonNamingPolicy em seu construtor, que especifica uma política de nomenclatura personalizada para formatar nomes de propriedades.

Para definir um nome personalizado para uma propriedade dentro de um modelo, use o atributo [JsonPropertyName] na propriedade:

public class SampleModel
{
    [Range(1, 10)]
    [JsonPropertyName("sampleValue")]
    public int Value { get; set; }
}

A ValidationProblemDetails resposta retornada para o modelo anterior quando a Value propriedade é inválida usa uma chave de erro, sampleValueconforme mostrado no exemplo a seguir:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-00000000000000000000000000000000-000000000000000-00",
  "errors": {
    "sampleValue": [
      "The field Value must be between 1 and 10."
    ]
  }
}

Para formatar a ValidationProblemDetails resposta usando Newtonsoft.Json, use NewtonsoftJsonValidationMetadataProvider:

builder.Services.AddControllers()
    .AddNewtonsoftJson();

builder.Services.Configure<MvcOptions>(options =>
{
    options.ModelMetadataDetailsProviders.Add(
        new NewtonsoftJsonValidationMetadataProvider());
});

Por padrão, NewtonsoftJsonValidationMetadataProvider formata nomes de propriedade como camelCase. NewtonsoftJsonValidationMetadataProvider também aceita uma implementação de NamingPolicy em seu construtor, que especifica uma política de nomenclatura personalizada para formatar nomes de propriedades. Para definir um nome personalizado para uma propriedade dentro de um modelo, use o [JsonProperty] atributo.

Especificar um formato

Para restringir os formatos de resposta, aplique o [Produces] filtro. Como a maioria dos Filtros, [Produces] pode ser aplicado na ação, no controlador ou no escopo global:

[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class TodoItemsController : ControllerBase

O filtro anterior [Produces] :

  • Força todas as ações dentro do controlador a retornar JSrespostas formatadas em ON para POCOs (Objetos CLR Antigos Simples) ou ObjectResult seus tipos derivados.
  • Retorne JSrespostas formatadas em ON mesmo se outros formadores estiverem configurados e o cliente especificar um formato diferente.

Para obter mais informações, consulte Filtros.

Formatores de maiúsculas e minúsculas especiais

Alguns casos especiais são implementados com formatadores internos. Por padrão, string os tipos de retorno são formatados como texto/sem formatação (texto/html , se solicitado por meio do Accept cabeçalho). Esse comportamento pode ser excluído removendo o StringOutputFormatter. Os formatadores são removidos em Program.cs. Ações que têm um tipo de retorno de objeto de modelo retornam 204 No Content ao retornar null. Esse comportamento pode ser excluído removendo o HttpNoContentOutputFormatter. O código a seguir remove o StringOutputFormatter e o HttpNoContentOutputFormatter.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    // using Microsoft.AspNetCore.Mvc.Formatters;
    options.OutputFormatters.RemoveType<StringOutputFormatter>();
    options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
});

Sem os StringOutputFormattertipos de retorno dos formatos string de formatador ON internosJS. Se o formatador ON interno JSfor removido e um formatador XML estiver disponível, os formatos string de formatador XML retornarão tipos. Caso contrário, string os tipos de retorno retornarão 406 Not Acceptable.

Sem o HttpNoContentOutputFormatter, os objetos nulos são formatados com o formatador configurado. Por exemplo:

  • O JSformatador ON retorna uma resposta com um corpo de null.
  • O formatador XML retorna um elemento XML vazio com o conjunto de atributos xsi:nil="true" .

Mapeamentos de URL de formato de resposta

Os clientes podem solicitar um formato específico como parte da URL, por exemplo:

  • Na cadeia de caracteres de consulta ou parte do caminho.
  • Usando uma extensão de arquivo específica de formato, como .xml ou .json.

O mapeamento do caminho da solicitação deve ser especificado na rota que está sendo usada pela API. Por exemplo:

[ApiController]
[Route("api/[controller]")]
[FormatFilter]
public class TodoItemsController : ControllerBase
{
    private readonly TodoItemStore _todoItemStore;

    public TodoItemsController(TodoItemStore todoItemStore)
        => _todoItemStore = todoItemStore;

    [HttpGet("{id:long}.{format?}")]
    public TodoItem? GetById(long id)
        => _todoItemStore.GetById(id);

A rota anterior permite que o formato solicitado seja especificado usando uma extensão de arquivo opcional. O [FormatFilter] atributo verifica a existência do valor de formato no RouteData formato e mapeia o formato de resposta para o formatador apropriado quando a resposta é criada.

Rota Formatador
/api/todoitems/5 O formatador de saída padrão
/api/todoitems/5.json O JSformatador ON (se configurado)
/api/todoitems/5.xml O formatador XML (se configurado)

Desserialização polimórfica

Os recursos internos fornecem um intervalo limitado de serialização polimórfica, mas nenhum suporte para desserialização. A desserialização requer um conversor personalizado. Consulte a desserialização polimórfica para obter uma amostra completa de desserialização polimórfica.

Recursos adicionais