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'intestazioneAccept
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:
- Restituisce
406 Not Acceptable
se MvcOptions.ReturnHttpNotAcceptable è impostato sutrue
o - - Prova a trovare il primo formattatore in grado di produrre una risposta.
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.Json
formattatori basati su
Per configurare le funzionalità per i System.Text.Json
formattatori 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.Json
del supporto per il formato JSON basato su
I formattatori JSON predefiniti usano System.Text.Json
. Per usare i Newtonsoft.Json
formattatori 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
:
- Formattatori di input e output che leggono e scrivono JSON
- JsonResult
- Patch JSON
- IJsonHelper
- TempData
Alcune funzionalità potrebbero non funzionare correttamente con System.Text.Json
i formattatori basati su e richiedono un riferimento ai Newtonsoft.Json
formattatori basati su . Continuare a usare i Newtonsoft.Json
formattatori 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.Json
formattatori 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>();
});
StringOutputFormatter
Senza , 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'intestazioneAccept
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/json
tipi di supporti , text/json
e 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:
- Restituisce
406 Not Acceptable
se MvcOptions.ReturnHttpNotAcceptable è impostato sutrue
o - - Prova a trovare il primo formattatore in grado di produrre una risposta.
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
:
- Formattatori di input e output che leggono e scrivono JSON
- JsonResult
- Patch JSON
- IJsonHelper
- TempData
Alcune funzionalità potrebbero non funzionare correttamente con System.Text.Json
i formattatori basati su e richiedono un riferimento ai Newtonsoft.Json
formattatori basati su . Continuare a usare i Newtonsoft.Json
formattatori 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.Json
formattatori 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>();
});
}
StringOutputFormatter
Senza , 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'intestazioneAccept
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:
- Restituisce
406 Not Acceptable
se MvcOptions.ReturnHttpNotAcceptable è impostato sutrue
o - - Prova a trovare il primo formattatore in grado di produrre una risposta.
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.Json
formattatori basati su
Per configurare le funzionalità per i System.Text.Json
formattatori 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.Json
del supporto per il formato JSON basato su
I formattatori JSON predefiniti usano System.Text.Json
. Per usare i Newtonsoft.Json
formattatori 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
:
- Formattatori di input e output che leggono e scrivono JSON
- JsonResult
- Patch JSON
- IJsonHelper
- TempData
Alcune funzionalità potrebbero non funzionare correttamente con System.Text.Json
i formattatori basati su e richiedono un riferimento ai Newtonsoft.Json
formattatori basati su . Continuare a usare i Newtonsoft.Json
formattatori 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.Json
formattatori 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.Json
basata 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>();
});
StringOutputFormatter
Senza , 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.