Formattare i dati di risposta nell'API Web ASP.NET Core

ASP.NET Core MVC supporta la formattazione dei dati di risposta, usando formati specificati o in risposta alla richiesta di un client.

Risultati azione specifici del formato

Alcuni tipi di risultati di azioni sono specifici di un particolare formato, ad esempio JsonResult e ContentResult. Le azioni possono restituire risultati che usano sempre un formato specificato, ignorando la richiesta di un client per un formato diverso. Ad esempio, la restituzione restituisce JsonResult dati in formato JSON e la restituzione restituisce ContentResult dati stringa in formato testo normale.

Non è necessaria un'azione per restituire un tipo specifico. ASP.NET Core supporta qualsiasi valore restituito dall'oggetto. I risultati delle azioni che restituiscono oggetti che non IActionResult sono tipi vengono serializzati usando l'implementazione appropriata IOutputFormatter . Per altre informazioni, vedere Tipi restituiti di azioni del controller in ASP.NET API Web core.

Per impostazione predefinita, il metodo ControllerBase.Ok helper predefinito restituisce dati in formato JSON:

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

Il codice di esempio restituisce un elenco di elementi todo. Usando gli strumenti di sviluppo del browser F12 o http-repl con il codice precedente viene visualizzato:

  • Intestazione della risposta contenente il tipo di contenuto: application/json; charset=utf-8.
  • Intestazioni delle richieste. Ad esempio, l'intestazione Accept . L'intestazione Accept viene ignorata dal codice precedente.

Per restituire dati in formato testo normale, usare ContentResult e l'helper Content:

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

Nel codice precedente, l'oggetto Content-Type restituito è text/plain.

Per le azioni con più tipi restituiti, restituire IActionResult. Ad esempio, quando si restituiscono codici di stato HTTP diversi in base al risultato dell'operazione.

Negoziazione del contenuto

La negoziazione del contenuto si verifica quando il client specifica un'intestazione Accept. Il formato predefinito usato da ASP.NET Core è JSON. La negoziazione del contenuto è:

  • Implementato da ObjectResult.
  • Integrato nei risultati dell'azione specifica del codice di stato restituiti dai metodi helper. I metodi helper dei risultati dell'azione sono basati su ObjectResult.

Quando viene restituito un tipo di modello, il tipo restituito è ObjectResult.

Il metodo di azione seguente usa i metodi helper 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);
}

Per impostazione predefinita, ASP.NET Core supporta i tipi di supporto seguenti:

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

Strumenti come Fiddler o curl possono impostare l'intestazione della Accept richiesta per specificare il formato restituito. Quando l'intestazione Accept contiene un tipo supportato dal server, viene restituito tale tipo. Nella sezione successiva viene illustrato come aggiungere altri formattatori.

Le azioni del controller possono restituire oggetti POCO (Plain Old CLR Objects). Quando viene restituito un POCO, il runtime crea automaticamente un oggetto ObjectResult che esegue il wrapping dell'oggetto. Il client ottiene l'oggetto serializzato formattato. Se l'oggetto restituito è null, viene restituita una 204 No Content risposta.

Nell'esempio seguente viene restituito un tipo di oggetto:

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

Nel codice precedente una richiesta di un elemento todo valido restituisce una 200 OK risposta. Una richiesta di un elemento todo non valido restituisce una 204 No Content risposta.

Intestazione Accept

La negoziazione del contenuto viene eseguita quando viene visualizzata un'intestazione Accept nella richiesta. Quando una richiesta contiene un'intestazione accept, ASP.NET Core:

  • Enumera i tipi di supporti nell'intestazione accept nell'ordine delle preferenze.
  • Prova a trovare un formattatore in grado di produrre una risposta in uno dei formati specificati.

Se non viene trovato alcun formattatore in grado di soddisfare la richiesta del client, ASP.NET Core:

Se non è configurato alcun formattatore per il formato richiesto, viene utilizzato il primo formattatore in grado di formattare l'oggetto. Se nella richiesta non viene visualizzata alcuna Accept intestazione:

  • Il primo formattatore in grado di gestire l'oggetto viene usato per serializzare la risposta.
  • Non c'è nessuna negoziazione in atto. Il server determina il formato da restituire.

Se l'intestazione Accept contiene */*, l'intestazione viene ignorata a meno che RespectBrowserAcceptHeader non sia impostata su true in MvcOptions.

Browser e negoziazione del contenuto

A differenza dei client API tipici, i Web browser forniscono Accept intestazioni. I Web browser specificano molti formati, inclusi i caratteri jolly. Per impostazione predefinita, quando il framework rileva che la richiesta proviene da un browser:

  • L'intestazione Accept viene ignorata.
  • Il contenuto viene restituito in JSON, se non diversamente configurato.

Questo approccio offre un'esperienza più coerente tra i browser quando si usano le API.

Per configurare un'app in modo che rispetti le intestazioni del browser, impostare la RespectBrowserAcceptHeader proprietà su true:

var builder = WebApplication.CreateBuilder(args);

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

Configurare i formattatori

Le app che devono supportare formati aggiuntivi possono aggiungere i pacchetti NuGet appropriati e configurare il supporto. Esistono formattatori separati per input e output. I formattatori di input vengono usati dall'associazione di modelli. I formattatori di output vengono usati per formattare le risposte. Per informazioni sulla creazione di un formattatore personalizzato, vedere Formattatori personalizzati.

Aggiungere il supporto per il formato XML

Per configurare i formattatori XML implementati tramite XmlSerializer, chiamare AddXmlSerializerFormatters:

var builder = WebApplication.CreateBuilder(args);

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

Quando si usa il codice precedente, i metodi controller restituiscono il formato appropriato in base all'intestazione della Accept richiesta.

Configurare System.Text.Jsonformattatori basati su

Per configurare le funzionalità per i System.Text.Jsonformattatori basati su , usare Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. Il codice evidenziato seguente configura la formattazione PascalCase anziché la formattazione camelCase predefinita:

var builder = WebApplication.CreateBuilder(args);

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

Il metodo di azione seguente chiama ControllerBase.Problem per creare una ProblemDetails risposta:

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

Una ProblemDetails risposta è sempre camelCase, anche quando l'app imposta il formato su PascalCase. ProblemDetails segue RFC 7807, che specifica lettere minuscole.

Per configurare le opzioni di serializzazione di output per azioni specifiche, usare JsonResult. Ad esempio:

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

Aggiunta Newtonsoft.Jsondel supporto per il formato JSON basato su

I formattatori JSON predefiniti usano System.Text.Json. Per usare i Newtonsoft.Jsonformattatori basati su , installare il Microsoft.AspNetCore.Mvc.NewtonsoftJson pacchetto NuGet e configurarlo in Program.cs:

var builder = WebApplication.CreateBuilder(args);

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

Nel codice precedente la chiamata a AddNewtonsoftJson configura le funzionalità api Web, MVC e Razor Pages seguenti da usare Newtonsoft.Json:

Alcune funzionalità potrebbero non funzionare correttamente con System.Text.Jsoni formattatori basati su e richiedono un riferimento ai Newtonsoft.Jsonformattatori basati su . Continuare a usare i Newtonsoft.Jsonformattatori basati su quando l'app:

  • Usa gli Newtonsoft.Json attributi. Ad esempio, [JsonProperty] o [JsonIgnore].
  • Personalizza le impostazioni di serializzazione.
  • Si basa sulle funzionalità fornite Newtonsoft.Json .

Per configurare le funzionalità per i Newtonsoft.Jsonformattatori basati su , usare SerializerSettings:

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

Per configurare le opzioni di serializzazione di output per azioni specifiche, usare JsonResult. Ad esempio:

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

Specificare un formato

Per limitare i formati di risposta, applicare il [Produces] filtro. Analogamente alla maggior parte dei filtri, [Produces] può essere applicato all'azione, al controller o all'ambito globale:

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

Filtro precedente [Produces] :

  • Forza tutte le azioni all'interno del controller a restituire risposte in formato JSON per poCO (Plain Old CLR Objects) o ObjectResult i relativi tipi derivati.
  • Restituisce risposte in formato JSON anche se sono configurati altri formattatori e il client specifica un formato diverso.

Per altre informazioni, vedere Filtri.

Formattatori di maiuscole e minuscole speciali

Alcuni casi speciali vengono implementati tramite formattatori predefiniti. Per impostazione predefinita, string i tipi restituiti vengono formattati come testo/normale (testo/html se richiesto tramite l'intestazione Accept ). Questo comportamento può essere eliminato rimuovendo .StringOutputFormatter I formattatori vengono rimossi in Program.cs. Le azioni con un tipo restituito oggetto modello restituiscono 204 No Content durante la restituzione di null. Questo comportamento può essere eliminato rimuovendo .HttpNoContentOutputFormatter Il codice seguente rimuove StringOutputFormatter e HttpNoContentOutputFormatter.

var builder = WebApplication.CreateBuilder(args);

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

StringOutputFormatterSenza , i formati string predefiniti del formattatore JSON restituiscono tipi. Se il formattatore JSON predefinito viene rimosso e un formattatore XML è disponibile, il formattatore XML formatta string i tipi restituiti. In caso contrario, string i tipi restituiti restituiscono 406 Not Acceptable.

Senza HttpNoContentOutputFormatter, gli oggetti Null vengono formattati tramite il formattatore configurato. Ad esempio:

  • Il formattatore JSON restituisce una risposta con un corpo di null.
  • Il formattatore XML restituisce un elemento XML vuoto con il set di attributi xsi:nil="true" .

Mapping url formato risposta

I client possono richiedere un formato specifico come parte dell'URL, ad esempio:

  • Nella stringa di query o nella parte del percorso.
  • Usando un'estensione di file specifica del formato, ad esempio .xml o .json.

Il mapping dal percorso della richiesta deve essere specificato nella route usata dall'API. Ad esempio:

[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);

La route precedente consente di specificare il formato richiesto usando un'estensione di file facoltativa. L'attributo [FormatFilter] verifica l'esistenza del valore di formato in RouteData e esegue il mapping del formato di risposta al formattatore appropriato al momento della creazione della risposta.

Itinerario Formattatore
/api/todoitems/5 Formattatore di output predefinito
/api/todoitems/5.json Formattatore JSON (se configurato)
/api/todoitems/5.xml Formattatore XML (se configurato)

Deserializzazione polimorfica

Le funzionalità predefinite offrono una gamma limitata di serializzazione polimorfica, ma non supportano affatto la deserializzazione. La deserializzazione richiede un convertitore personalizzato. Per un esempio completo di deserializzazione polimorfica, vedere Deserializzazione polimorfica.

Risorse aggiuntive

ASP.NET Core MVC supporta la formattazione dei dati di risposta. I dati di risposta possono essere formattati usando formati specifici o in risposta al formato richiesto dal client.

Visualizzare o scaricare il codice di esempio (procedura per il download)

Risultati azione specifici del formato

Alcuni tipi di risultati di azioni sono specifici di un particolare formato, ad esempio JsonResult e ContentResult. Le azioni possono restituire risultati formattati in un formato specifico, indipendentemente dalle preferenze client. Ad esempio, la restituzione restituisce JsonResult dati in formato JSON. La restituzione o una stringa restituisce ContentResult dati stringa in formato testo normale.

Non è necessaria un'azione per restituire un tipo specifico. ASP.NET Core supporta qualsiasi valore restituito dall'oggetto. I risultati delle azioni che restituiscono oggetti che non IActionResult sono tipi vengono serializzati usando l'implementazione appropriata IOutputFormatter . Per altre informazioni, vedere Tipi restituiti di azioni del controller in ASP.NET API Web core.

Il metodo Ok helper predefinito restituisce dati in formato JSON:

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

Il download di esempio restituisce l'elenco degli autori. Uso degli strumenti di sviluppo del browser F12 o http-repl con il codice precedente:

  • Viene visualizzata l'intestazione della risposta contenente content-type: application/json; charset=utf-8 .
  • Vengono visualizzate le intestazioni della richiesta. Ad esempio, l'intestazione Accept . L'intestazione Accept viene ignorata dal codice precedente.

Per restituire dati in formato testo normale, usare ContentResult e l'helper Content:

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

Nel codice precedente, l'oggetto Content-Type restituito è text/plain. Restituzione di una stringa di Content-Type text/plain:

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

Per le azioni con più tipi restituiti, restituire IActionResult. Ad esempio, restituendo codici di stato HTTP diversi in base al risultato delle operazioni eseguite.

Negoziazione del contenuto

La negoziazione del contenuto si verifica quando il client specifica un'intestazione Accept. Il formato predefinito usato da ASP.NET Core è JSON. La negoziazione del contenuto è:

  • Implementato da ObjectResult.
  • Integrato nei risultati dell'azione specifica del codice di stato restituiti dai metodi helper. I metodi helper dei risultati dell'azione sono basati su ObjectResult.

Quando viene restituito un tipo di modello, il tipo restituito è ObjectResult.

Il metodo di azione seguente usa i metodi helper 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);
}

Per impostazione predefinita, ASP.NET Core supporta i application/jsontipi di supporti , text/jsone text/plain . Strumenti come Fiddler o http-repl possono impostare l'intestazione della Accept richiesta per specificare il formato restituito. Quando l'intestazione Accept contiene un tipo supportato dal server, viene restituito tale tipo. Nella sezione successiva viene illustrato come aggiungere altri formattatori.

Le azioni del controller possono restituire oggetti POCO (Plain Old CLR Objects). Quando viene restituito un POCO, il runtime crea automaticamente un oggetto ObjectResult che esegue il wrapping dell'oggetto. Il client ottiene l'oggetto serializzato formattato. Se l'oggetto restituito è null, viene restituita una 204 No Content risposta.

Restituzione di un tipo di oggetto:

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

Nel codice precedente una richiesta di un alias autore valido restituisce una 200 OK risposta con i dati dell'autore. Una richiesta per un alias non valido restituisce una 204 No Content risposta.

Intestazione Accept

La negoziazione del contenuto viene eseguita quando viene visualizzata un'intestazione Accept nella richiesta. Quando una richiesta contiene un'intestazione accept, ASP.NET Core:

  • Enumera i tipi di supporti nell'intestazione accept nell'ordine delle preferenze.
  • Prova a trovare un formattatore in grado di produrre una risposta in uno dei formati specificati.

Se non viene trovato alcun formattatore in grado di soddisfare la richiesta del client, ASP.NET Core:

Se non è configurato alcun formattatore per il formato richiesto, viene utilizzato il primo formattatore in grado di formattare l'oggetto. Se nella richiesta non viene visualizzata alcuna Accept intestazione:

  • Il primo formattatore in grado di gestire l'oggetto viene usato per serializzare la risposta.
  • Non c'è nessuna negoziazione in atto. Il server determina il formato da restituire.

Se l'intestazione Accept contiene */*, l'intestazione viene ignorata a meno che RespectBrowserAcceptHeader non sia impostata su true in MvcOptions.

Browser e negoziazione del contenuto

A differenza dei client API tipici, i Web browser forniscono Accept intestazioni. I Web browser specificano molti formati, inclusi i caratteri jolly. Per impostazione predefinita, quando il framework rileva che la richiesta proviene da un browser:

  • L'intestazione Accept viene ignorata.
  • Il contenuto viene restituito in JSON, se non diversamente configurato.

Questo approccio offre un'esperienza più coerente tra i browser quando si usano le API.

Per configurare un'app in modo che accetti le intestazioni del browser, impostare su RespectBrowserAcceptHeader true:

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

Configurare i formattatori

Le app che devono supportare formati aggiuntivi possono aggiungere i pacchetti NuGet appropriati e configurare il supporto. Esistono formattatori separati per input e output. I formattatori di input vengono usati dall'associazione di modelli. I formattatori di output vengono usati per formattare le risposte. Per informazioni sulla creazione di un formattatore personalizzato, vedere Formattatori personalizzati.

Aggiungere il supporto per il formato XML

I formattatori XML implementati tramite XmlSerializer vengono configurati chiamando AddXmlSerializerFormatters:

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

Il codice precedente serializza i risultati usando XmlSerializer.

Quando si usa il codice precedente, i metodi controller restituiscono il formato appropriato in base all'intestazione della Accept richiesta.

Configurare System.Text.Json formattatori basati

Le funzionalità per i System.Text.Json formattatori basati possono essere configurate tramite Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. La formattazione predefinita è camelCase. Il codice evidenziato seguente imposta la formattazione PascalCase:

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

Il metodo di azione seguente chiama ControllerBase.Problem per creare una ProblemDetails risposta:

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

Con il codice precedente:

  • https://localhost:5001/WeatherForecast/temperature restituisce PascalCase.
  • https://localhost:5001/WeatherForecast/error restituisce camelCase. La risposta di errore è sempre camelCase, anche quando l'app imposta il formato su PascalCase. ProblemDetails segue RFC 7807, che specifica lettere minuscole

Il codice seguente imposta PascalCase e aggiunge un convertitore personalizzato:

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

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

Le opzioni di serializzazione di output, in base all'azione, possono essere configurate usando JsonResult. Ad esempio:

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

Aggiungere il supporto del formato JSON basato su Newtonsoft.Json

I formattatori JSON predefiniti sono basati su System.Text.Json. Il supporto per Newtonsoft.Json formattatori e funzionalità basati è disponibile installando il Microsoft.AspNetCore.Mvc.NewtonsoftJson pacchetto NuGet e configurandolo in Startup.ConfigureServices.

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

Nel codice precedente la chiamata a AddNewtonsoftJson configura le funzionalità api Web, MVC e Razor Pages seguenti da usare Newtonsoft.Json:

Alcune funzionalità potrebbero non funzionare correttamente con System.Text.Jsoni formattatori basati su e richiedono un riferimento ai Newtonsoft.Jsonformattatori basati su . Continuare a usare i Newtonsoft.Jsonformattatori basati su quando l'app:

  • Usa gli Newtonsoft.Json attributi. Ad esempio, [JsonProperty] o [JsonIgnore].
  • Personalizza le impostazioni di serializzazione.
  • Si basa sulle funzionalità fornite Newtonsoft.Json .

Le funzionalità per i Newtonsoft.Jsonformattatori basati su possono essere configurate 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());
});

Le opzioni di serializzazione di output, in base all'azione, possono essere configurate usando JsonResult. Ad esempio:

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

Specificare un formato

Per limitare i formati di risposta, applicare il [Produces] filtro. Analogamente alla maggior parte dei filtri, [Produces] può essere applicato all'azione, al controller o all'ambito globale:

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

Filtro precedente [Produces] :

  • Forza tutte le azioni all'interno del controller a restituire risposte in formato JSON per poCO (Plain Old CLR Objects) o ObjectResult i relativi tipi derivati.
  • Se sono configurati altri formattatori e il client specifica un formato diverso, viene restituito JSON.

Per altre informazioni, vedere Filtri.

Formattatori di maiuscole e minuscole speciali

Alcuni casi speciali vengono implementati tramite formattatori predefiniti. Per impostazione predefinita, string i tipi restituiti vengono formattati come testo/normale (testo/html se richiesto tramite l'intestazione Accept ). Questo comportamento può essere eliminato rimuovendo .StringOutputFormatter I formattatori vengono rimossi nel ConfigureServices metodo . Le azioni con un tipo restituito oggetto modello restituiscono 204 No Content durante la restituzione di null. Questo comportamento può essere eliminato rimuovendo .HttpNoContentOutputFormatter Il codice seguente rimuove StringOutputFormatter e HttpNoContentOutputFormatter.

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

StringOutputFormatterSenza , i formati string predefiniti del formattatore JSON restituiscono tipi. Se il formattatore JSON predefinito viene rimosso e un formattatore XML è disponibile, il formattatore XML formatta string i tipi restituiti. In caso contrario, string i tipi restituiti restituiscono 406 Not Acceptable.

Senza HttpNoContentOutputFormatter, gli oggetti Null vengono formattati tramite il formattatore configurato. Ad esempio:

  • Il formattatore JSON restituisce una risposta con un corpo di null.
  • Il formattatore XML restituisce un elemento XML vuoto con il set di attributi xsi:nil="true" .

Mapping url formato risposta

I client possono richiedere un formato specifico come parte dell'URL, ad esempio:

  • Nella stringa di query o nella parte del percorso.
  • Usando un'estensione di file specifica del formato, ad esempio .xml o .json.

Il mapping dal percorso della richiesta deve essere specificato nella route usata dall'API. Ad esempio:

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

La route precedente consente di specificare il formato richiesto come estensione di file facoltativa. L'attributo [FormatFilter] verifica l'esistenza del valore di formato in RouteData e esegue il mapping del formato di risposta al formattatore appropriato al momento della creazione della risposta.

Itinerario Formattatore
/api/products/5 Formattatore di output predefinito
/api/products/5.json Formattatore JSON (se configurato)
/api/products/5.xml Formattatore XML (se configurato)

ASP.NET Core MVC supporta la formattazione dei dati di risposta, usando formati specificati o in risposta alla richiesta di un client.

Risultati azione specifici del formato

Alcuni tipi di risultati di azioni sono specifici di un particolare formato, ad esempio JsonResult e ContentResult. Le azioni possono restituire risultati che usano sempre un formato specificato, ignorando la richiesta di un client per un formato diverso. Ad esempio, la restituzione restituisce JsonResult dati in formato JSON e la restituzione restituisce ContentResult dati stringa in formato testo normale.

Non è necessaria un'azione per restituire un tipo specifico. ASP.NET Core supporta qualsiasi valore restituito dall'oggetto. I risultati delle azioni che restituiscono oggetti che non IActionResult sono tipi vengono serializzati usando l'implementazione appropriata IOutputFormatter . Per altre informazioni, vedere Tipi restituiti di azioni del controller in ASP.NET API Web core.

Per impostazione predefinita, il metodo ControllerBase.Ok helper predefinito restituisce dati in formato JSON:

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

Il codice di esempio restituisce un elenco di elementi todo. Usando gli strumenti di sviluppo del browser F12 o http-repl con il codice precedente viene visualizzato:

  • Intestazione della risposta contenente il tipo di contenuto: application/json; charset=utf-8.
  • Intestazioni delle richieste. Ad esempio, l'intestazione Accept . L'intestazione Accept viene ignorata dal codice precedente.

Per restituire dati in formato testo normale, usare ContentResult e l'helper Content:

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

Nel codice precedente, l'oggetto Content-Type restituito è text/plain.

Per le azioni con più tipi restituiti, restituire IActionResult. Ad esempio, quando si restituiscono codici di stato HTTP diversi in base al risultato dell'operazione.

Negoziazione del contenuto

La negoziazione del contenuto si verifica quando il client specifica un'intestazione Accept. Il formato predefinito usato da ASP.NET Core è JSON. La negoziazione del contenuto è:

  • Implementato da ObjectResult.
  • Integrato nei risultati dell'azione specifica del codice di stato restituiti dai metodi helper. I metodi helper dei risultati dell'azione sono basati su ObjectResult.

Quando viene restituito un tipo di modello, il tipo restituito è ObjectResult.

Il metodo di azione seguente usa i metodi helper 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);
}

Per impostazione predefinita, ASP.NET Core supporta i tipi di supporto seguenti:

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

Strumenti come Fiddler o http-repl possono impostare l'intestazione della Accept richiesta per specificare il formato restituito. Quando l'intestazione Accept contiene un tipo supportato dal server, viene restituito tale tipo. Nella sezione successiva viene illustrato come aggiungere altri formattatori.

Le azioni del controller possono restituire oggetti POCO (Plain Old CLR Objects). Quando viene restituito un POCO, il runtime crea automaticamente un oggetto ObjectResult che esegue il wrapping dell'oggetto. Il client ottiene l'oggetto serializzato formattato. Se l'oggetto restituito è null, viene restituita una 204 No Content risposta.

Nell'esempio seguente viene restituito un tipo di oggetto:

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

Nel codice precedente una richiesta di un elemento todo valido restituisce una 200 OK risposta. Una richiesta di un elemento todo non valido restituisce una 204 No Content risposta.

Intestazione Accept

La negoziazione del contenuto viene eseguita quando viene visualizzata un'intestazione Accept nella richiesta. Quando una richiesta contiene un'intestazione accept, ASP.NET Core:

  • Enumera i tipi di supporti nell'intestazione accept nell'ordine delle preferenze.
  • Prova a trovare un formattatore in grado di produrre una risposta in uno dei formati specificati.

Se non viene trovato alcun formattatore in grado di soddisfare la richiesta del client, ASP.NET Core:

Se non è configurato alcun formattatore per il formato richiesto, viene utilizzato il primo formattatore in grado di formattare l'oggetto. Se nella richiesta non viene visualizzata alcuna Accept intestazione:

  • Il primo formattatore in grado di gestire l'oggetto viene usato per serializzare la risposta.
  • Non c'è nessuna negoziazione in atto. Il server determina il formato da restituire.

Se l'intestazione Accept contiene */*, l'intestazione viene ignorata a meno che RespectBrowserAcceptHeader non sia impostata su true in MvcOptions.

Browser e negoziazione del contenuto

A differenza dei client API tipici, i Web browser forniscono Accept intestazioni. I Web browser specificano molti formati, inclusi i caratteri jolly. Per impostazione predefinita, quando il framework rileva che la richiesta proviene da un browser:

  • L'intestazione Accept viene ignorata.
  • Il contenuto viene restituito in JSON, se non diversamente configurato.

Questo approccio offre un'esperienza più coerente tra i browser quando si usano le API.

Per configurare un'app in modo che rispetti le intestazioni del browser, impostare la RespectBrowserAcceptHeader proprietà su true:

var builder = WebApplication.CreateBuilder(args);

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

Configurare i formattatori

Le app che devono supportare formati aggiuntivi possono aggiungere i pacchetti NuGet appropriati e configurare il supporto. Esistono formattatori separati per input e output. I formattatori di input vengono usati dall'associazione di modelli. I formattatori di output vengono usati per formattare le risposte. Per informazioni sulla creazione di un formattatore personalizzato, vedere Formattatori personalizzati.

Aggiungere il supporto per il formato XML

Per configurare i formattatori XML implementati tramite XmlSerializer, chiamare AddXmlSerializerFormatters:

var builder = WebApplication.CreateBuilder(args);

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

Quando si usa il codice precedente, i metodi controller restituiscono il formato appropriato in base all'intestazione della Accept richiesta.

Configurare System.Text.Jsonformattatori basati su

Per configurare le funzionalità per i System.Text.Jsonformattatori basati su , usare Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. Il codice evidenziato seguente configura la formattazione PascalCase anziché la formattazione camelCase predefinita:

var builder = WebApplication.CreateBuilder(args);

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

Per configurare le opzioni di serializzazione di output per azioni specifiche, usare JsonResult. Ad esempio:

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

Aggiunta Newtonsoft.Jsondel supporto per il formato JSON basato su

I formattatori JSON predefiniti usano System.Text.Json. Per usare i Newtonsoft.Jsonformattatori basati su , installare il Microsoft.AspNetCore.Mvc.NewtonsoftJson pacchetto NuGet e configurarlo in Program.cs:

var builder = WebApplication.CreateBuilder(args);

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

Nel codice precedente la chiamata a AddNewtonsoftJson configura le funzionalità api Web, MVC e Razor Pages seguenti da usare Newtonsoft.Json:

Alcune funzionalità potrebbero non funzionare correttamente con System.Text.Jsoni formattatori basati su e richiedono un riferimento ai Newtonsoft.Jsonformattatori basati su . Continuare a usare i Newtonsoft.Jsonformattatori basati su quando l'app:

  • Usa gli Newtonsoft.Json attributi. Ad esempio, [JsonProperty] o [JsonIgnore].
  • Personalizza le impostazioni di serializzazione.
  • Si basa sulle funzionalità fornite Newtonsoft.Json .

Per configurare le funzionalità per i Newtonsoft.Jsonformattatori basati su , usare SerializerSettings:

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

Per configurare le opzioni di serializzazione di output per azioni specifiche, usare JsonResult. Ad esempio:

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

Formato ProblemDetails e ValidationProblemDetails risposte

Il metodo di azione seguente chiama ControllerBase.Problem per creare una ProblemDetails risposta:

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

Una ProblemDetails risposta è sempre camelCase, anche quando l'app imposta il formato su PascalCase. ProblemDetails segue RFC 7807, che specifica lettere minuscole.

Quando l'attributo [ApiController] viene applicato a una classe controller, il controller crea una ValidationProblemDetails risposta quando la convalida del modello ha esito negativo. Questa risposta include un dizionario che usa i nomi delle proprietà del modello come chiavi di errore, senza modifiche. Ad esempio, il modello seguente include una singola proprietà che richiede la convalida:

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

Per impostazione predefinita, la ValidationProblemDetails risposta restituita quando la Value proprietà non è valida usa una chiave di errore di Value, come illustrato nell'esempio seguente:

{
  "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."
    ]
  }
}

Per formattare i nomi delle proprietà usati come chiavi di errore, aggiungere un'implementazione di IMetadataDetailsProvider alla MvcOptions.ModelMetadataDetailsProviders raccolta. Nell'esempio seguente viene aggiunta un'implementazione System.Text.Jsonbasata su , SystemTextJsonValidationMetadataProvider, che formatta i nomi delle proprietà come camelCase per impostazione predefinita:

builder.Services.AddControllers();

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

SystemTextJsonValidationMetadataProvider accetta anche un'implementazione di JsonNamingPolicy nel relativo costruttore, che specifica un criterio di denominazione personalizzato per la formattazione dei nomi delle proprietà.

Per impostare un nome personalizzato per una proprietà all'interno di un modello, usare l'attributo [JsonPropertyName] nella proprietà :

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

La ValidationProblemDetails risposta restituita per il modello precedente quando la Value proprietà non è valida usa una chiave di errore di sampleValue, come illustrato nell'esempio seguente:

{
  "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."
    ]
  }
}

Per formattare la ValidationProblemDetails risposta usando Newtonsoft.Json, usare NewtonsoftJsonValidationMetadataProvider:

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

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

Per impostazione predefinita, NewtonsoftJsonValidationMetadataProvider formatta i nomi delle proprietà come camelCase. NewtonsoftJsonValidationMetadataProvider accetta anche un'implementazione di NamingPolicy nel relativo costruttore, che specifica un criterio di denominazione personalizzato per la formattazione dei nomi delle proprietà. Per impostare un nome personalizzato per una proprietà all'interno di un modello, usare l'attributo [JsonProperty] .

Specificare un formato

Per limitare i formati di risposta, applicare il [Produces] filtro. Analogamente alla maggior parte dei filtri, [Produces] può essere applicato all'azione, al controller o all'ambito globale:

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

Filtro precedente [Produces] :

  • Forza tutte le azioni all'interno del controller a restituire risposte in formato JSON per poCO (Plain Old CLR Objects) o ObjectResult i relativi tipi derivati.
  • Restituisce risposte in formato JSON anche se sono configurati altri formattatori e il client specifica un formato diverso.

Per altre informazioni, vedere Filtri.

Formattatori di maiuscole e minuscole speciali

Alcuni casi speciali vengono implementati tramite formattatori predefiniti. Per impostazione predefinita, string i tipi restituiti vengono formattati come testo/normale (testo/html se richiesto tramite l'intestazione Accept ). Questo comportamento può essere eliminato rimuovendo .StringOutputFormatter I formattatori vengono rimossi in Program.cs. Le azioni con un tipo restituito oggetto modello restituiscono 204 No Content durante la restituzione di null. Questo comportamento può essere eliminato rimuovendo .HttpNoContentOutputFormatter Il codice seguente rimuove StringOutputFormatter e HttpNoContentOutputFormatter.

var builder = WebApplication.CreateBuilder(args);

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

StringOutputFormatterSenza , i formati string predefiniti del formattatore JSON restituiscono tipi. Se il formattatore JSON predefinito viene rimosso e un formattatore XML è disponibile, il formattatore XML formatta string i tipi restituiti. In caso contrario, string i tipi restituiti restituiscono 406 Not Acceptable.

Senza HttpNoContentOutputFormatter, gli oggetti Null vengono formattati tramite il formattatore configurato. Ad esempio:

  • Il formattatore JSON restituisce una risposta con un corpo di null.
  • Il formattatore XML restituisce un elemento XML vuoto con il set di attributi xsi:nil="true" .

Mapping url formato risposta

I client possono richiedere un formato specifico come parte dell'URL, ad esempio:

  • Nella stringa di query o nella parte del percorso.
  • Usando un'estensione di file specifica del formato, ad esempio .xml o .json.

Il mapping dal percorso della richiesta deve essere specificato nella route usata dall'API. Ad esempio:

[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);

La route precedente consente di specificare il formato richiesto usando un'estensione di file facoltativa. L'attributo [FormatFilter] verifica l'esistenza del valore di formato in RouteData e esegue il mapping del formato di risposta al formattatore appropriato al momento della creazione della risposta.

Itinerario Formattatore
/api/todoitems/5 Formattatore di output predefinito
/api/todoitems/5.json Formattatore JSON (se configurato)
/api/todoitems/5.xml Formattatore XML (se configurato)

Deserializzazione polimorfica

Le funzionalità predefinite offrono una gamma limitata di serializzazione polimorfica, ma non supportano affatto la deserializzazione. La deserializzazione richiede un convertitore personalizzato. Per un esempio completo di deserializzazione polimorfica, vedere Deserializzazione polimorfica.

Risorse aggiuntive