Training
Module
Render API responses in ASP.NET Core Razor Pages - Training
Render API responses in ASP.NET Core Razor Pages
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
ASP.NET Core MVC supports formatting response data, using specified formats or in response to a client's request.
Some action result types are specific to a particular format, such as JsonResult and ContentResult. Actions can return results that always use a specified format, ignoring a client's request for a different format. For example, returning JsonResult
returns JSON-formatted data and returning ContentResult
returns plain-text-formatted string data.
An action isn't required to return any specific type. ASP.NET Core supports any object return value. Results from actions that return objects that aren't IActionResult types are serialized using the appropriate IOutputFormatter implementation. For more information, see Controller action return types in ASP.NET Core web API.
By default, the built-in helper method ControllerBase.Ok returns JSON-formatted data:
[HttpGet]
public IActionResult Get() =>
Ok(_todoItemStore.GetList());
The sample code returns a list of todo items. Using the F12 browser developer tools or http-repl with the previous code displays:
application/json; charset=utf-8
.Accept
header. The Accept
header is ignored by the preceding code.To return plain text formatted data, use ContentResult and the Content helper:
[HttpGet("Version")]
public ContentResult GetVersion() =>
Content("v1.0.0");
In the preceding code, the Content-Type
returned is text/plain
.
For actions with multiple return types, return IActionResult
. For example, when returning different HTTP status codes based on the result of the operation.
Content negotiation occurs when the client specifies an Accept header. The default format used by ASP.NET Core is JSON. Content negotiation is:
ObjectResult
.When a model type is returned, the return type is ObjectResult
.
The following action method uses the Ok
and NotFound
helper methods:
[HttpGet("{id:long}")]
public IActionResult GetById(long id)
{
var todo = _todoItemStore.GetById(id);
if (todo is null)
{
return NotFound();
}
return Ok(todo);
}
By default, ASP.NET Core supports the following media types:
application/json
text/json
text/plain
Tools such as Fiddler or curl can set the Accept
request header to specify the return format. When the Accept
header contains a type the server supports, that type is returned. The next section shows how to add additional formatters.
Controller actions can return POCOs (Plain Old CLR Objects). When a POCO is returned, the runtime automatically creates an ObjectResult
that wraps the object. The client gets the formatted serialized object. If the object being returned is null
, a 204 No Content
response is returned.
The following example returns an object type:
[HttpGet("{id:long}")]
public TodoItem? GetById(long id) =>
_todoItemStore.GetById(id);
In the preceding code, a request for a valid todo item returns a 200 OK
response. A request for an invalid todo item returns a 204 No Content
response.
Content negotiation takes place when an Accept
header appears in the request. When a request contains an accept header, ASP.NET Core:
If no formatter is found that can satisfy the client's request, ASP.NET Core:
406 Not Acceptable
if MvcOptions.ReturnHttpNotAcceptable is set to true
, or -If no formatter is configured for the requested format, the first formatter that can format the object is used. If no Accept
header appears in the request:
If the Accept header contains */*
, the Header is ignored unless RespectBrowserAcceptHeader
is set to true on MvcOptions.
Unlike typical API clients, web browsers supply Accept
headers. Web browsers specify many formats, including wildcards. By default, when the framework detects that the request is coming from a browser:
Accept
header is ignored.This approach provides a more consistent experience across browsers when consuming APIs.
To configure an app to respect browser accept headers, set the RespectBrowserAcceptHeader property to true
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
options.RespectBrowserAcceptHeader = true;
});
Apps that need to support extra formats can add the appropriate NuGet packages and configure support. There are separate formatters for input and output. Input formatters are used by Model Binding. Output formatters are used to format responses. For information on creating a custom formatter, see Custom Formatters.
To configure XML formatters implemented using XmlSerializer, call AddXmlSerializerFormatters:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddXmlSerializerFormatters();
When using the preceding code, controller methods return the appropriate format based on the request's Accept
header.
To configure features for the System.Text.Json
-based formatters, use Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. The following highlighted code configures PascalCase formatting instead of the default camelCase formatting:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = null;
});
The following action method calls ControllerBase.Problem to create a ProblemDetails response:
[HttpGet("Error")]
public IActionResult GetError() =>
Problem("Something went wrong.");
A ProblemDetails
response is always camelCase, even when the app sets the format to PascalCase. ProblemDetails
follows RFC 7807, which specifies lowercase.
To configure output serialization options for specific actions, use JsonResult
. For example:
[HttpGet]
public IActionResult Get() =>
new JsonResult(
_todoItemStore.GetList(),
new JsonSerializerOptions
{
PropertyNamingPolicy = null
});
The default JSON formatters use System.Text.Json
. To use the Newtonsoft.Json
-based formatters, install the Microsoft.AspNetCore.Mvc.NewtonsoftJson
NuGet package and configure it in Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddNewtonsoftJson();
In the preceding code, the call to AddNewtonsoftJson
configures the following Web API, MVC, and Razor Pages features to use Newtonsoft.Json
:
Some features may not work well with System.Text.Json
-based formatters and require a reference to the Newtonsoft.Json
-based formatters. Continue using the Newtonsoft.Json
-based formatters when the app:
Newtonsoft.Json
attributes. For example, [JsonProperty]
or [JsonIgnore]
.Newtonsoft.Json
provides.To configure features for the Newtonsoft.Json
-based formatters, use SerializerSettings:
builder.Services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
To configure output serialization options for specific actions, use JsonResult
. For example:
[HttpGet]
public IActionResult GetNewtonsoftJson() =>
new JsonResult(
_todoItemStore.GetList(),
new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver()
});
To restrict the response formats, apply the [Produces]
filter. Like most Filters, [Produces]
can be applied at the action, controller, or global scope:
[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class TodoItemsController : ControllerBase
The preceding [Produces]
filter:
For more information, see Filters.
Some special cases are implemented using built-in formatters. By default, string
return types are formatted as text/plain (text/html if requested via the Accept
header). This behavior can be deleted by removing the StringOutputFormatter. Formatters are removed in Program.cs
. Actions that have a model object return type return 204 No Content
when returning null
. This behavior can be deleted by removing the HttpNoContentOutputFormatter. The following code removes the StringOutputFormatter
and HttpNoContentOutputFormatter
.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
// using Microsoft.AspNetCore.Mvc.Formatters;
options.OutputFormatters.RemoveType<StringOutputFormatter>();
options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
});
Without the StringOutputFormatter
, the built-in JSON formatter formats string
return types. If the built-in JSON formatter is removed and an XML formatter is available, the XML formatter formats string
return types. Otherwise, string
return types return 406 Not Acceptable
.
Without the HttpNoContentOutputFormatter
, null objects are formatted using the configured formatter. For example:
null
.xsi:nil="true"
set.Clients can request a particular format as part of the URL, for example:
The mapping from request path should be specified in the route the API is using. For example:
[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);
The preceding route allows the requested format to be specified using an optional file extension. The [FormatFilter]
attribute checks for the existence of the format value in the RouteData
and maps the response format to the appropriate formatter when the response is created.
Route | Formatter |
---|---|
/api/todoitems/5 |
The default output formatter |
/api/todoitems/5.json |
The JSON formatter (if configured) |
/api/todoitems/5.xml |
The XML formatter (if configured) |
Built-in features provide a limited range of polymorphic serialization but no support for deserialization at all. Deserialization requires a custom converter. See Polymorphic deserialization for a complete sample of polymorphic deserialization.
ASP.NET Core MVC has support for formatting response data. Response data can be formatted using specific formats or in response to client requested format.
View or download sample code (how to download)
Some action result types are specific to a particular format, such as JsonResult and ContentResult. Actions can return results that are formatted in a particular format, regardless of client preferences. For example, returning JsonResult
returns JSON-formatted data. Returning ContentResult
or a string returns plain-text-formatted string data.
An action isn't required to return any specific type. ASP.NET Core supports any object return value. Results from actions that return objects that aren't IActionResult types are serialized using the appropriate IOutputFormatter implementation. For more information, see Controller action return types in ASP.NET Core web API.
The built-in helper method Ok returns JSON-formatted data:
// GET: api/authors
[HttpGet]
public ActionResult Get()
{
return Ok(_authors.List());
}
The sample download returns the list of authors. Using the F12 browser developer tools or http-repl with the previous code:
application/json; charset=utf-8
is displayed.Accept
header. The Accept
header is ignored by the preceding code.To return plain text formatted data, use ContentResult and the Content helper:
// GET api/authors/about
[HttpGet("About")]
public ContentResult About()
{
return Content("An API listing authors of docs.asp.net.");
}
In the preceding code, the Content-Type
returned is text/plain
. Returning a string delivers Content-Type
of text/plain
:
// GET api/authors/version
[HttpGet("version")]
public string Version()
{
return "Version 1.0.0";
}
For actions with multiple return types, return IActionResult
. For example, returning different HTTP status codes based on the result of operations performed.
Content negotiation occurs when the client specifies an Accept header. The default format used by ASP.NET Core is JSON. Content negotiation is:
ObjectResult
.When a model type is returned, the return type is ObjectResult
.
The following action method uses the Ok
and NotFound
helper methods:
// GET: api/authors/search?namelike=th
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
var result = _authors.GetByNameSubstring(namelike);
if (!result.Any())
{
return NotFound(namelike);
}
return Ok(result);
}
By default, ASP.NET Core supports application/json
, text/json
, and text/plain
media types. Tools such as Fiddler or http-repl can set the Accept
request header to specify the return format. When the Accept
header contains a type the server supports, that type is returned. The next section shows how to add additional formatters.
Controller actions can return POCOs (Plain Old CLR Objects). When a POCO is returned, the runtime automatically creates an ObjectResult
that wraps the object. The client gets the formatted serialized object. If the object being returned is null
, a 204 No Content
response is returned.
Returning an object type:
// GET api/authors/RickAndMSFT
[HttpGet("{alias}")]
public Author Get(string alias)
{
return _authors.GetByAlias(alias);
}
In the preceding code, a request for a valid author alias returns a 200 OK
response with the author's data. A request for an invalid alias returns a 204 No Content
response.
Content negotiation takes place when an Accept
header appears in the request. When a request contains an accept header, ASP.NET Core:
If no formatter is found that can satisfy the client's request, ASP.NET Core:
406 Not Acceptable
if MvcOptions.ReturnHttpNotAcceptable is set to true
, or -If no formatter is configured for the requested format, the first formatter that can format the object is used. If no Accept
header appears in the request:
If the Accept header contains */*
, the Header is ignored unless RespectBrowserAcceptHeader
is set to true on MvcOptions.
Unlike typical API clients, web browsers supply Accept
headers. Web browsers specify many formats, including wildcards. By default, when the framework detects that the request is coming from a browser:
Accept
header is ignored.This approach provides a more consistent experience across browsers when consuming APIs.
To configure an app to honor browser accept headers, set
RespectBrowserAcceptHeader to true
:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.RespectBrowserAcceptHeader = true; // false by default
});
}
Apps that need to support additional formats can add the appropriate NuGet packages and configure support. There are separate formatters for input and output. Input formatters are used by Model Binding. Output formatters are used to format responses. For information on creating a custom formatter, see Custom Formatters.
XML formatters implemented using XmlSerializer are configured by calling AddXmlSerializerFormatters:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddXmlSerializerFormatters();
}
The preceding code serializes results using XmlSerializer
.
When using the preceding code, controller methods return the appropriate format based on the request's Accept
header.
Features for the System.Text.Json
based formatters can be configured using Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. The default formatting is camelCase. The following highlighted code sets PascalCase formatting:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddJsonOptions(options =>
options.JsonSerializerOptions.PropertyNamingPolicy = null);
}
The following action method calls ControllerBase.Problem to create a ProblemDetails response:
[HttpGet("error")]
public IActionResult GetError()
{
return Problem("Something went wrong!");
}
With the preceding code:
https://localhost:5001/WeatherForecast/temperature
returns PascalCase.https://localhost:5001/WeatherForecast/error
returns camelCase. The error response is always camelCase, even when the app sets the format to PascalCase. ProblemDetails
follows RFC 7807, which specifies lower caseThe following code sets PascalCase and adds a custom converter:
services.AddControllers().AddJsonOptions(options =>
{
// Use the default property (Pascal) casing.
options.JsonSerializerOptions.PropertyNamingPolicy = null;
// Configure a custom converter.
options.JsonSerializerOptions.Converters.Add(new MyCustomJsonConverter());
});
Output serialization options, on a per-action basis, can be configured using JsonResult
. For example:
public IActionResult Get()
{
return Json(model, new JsonSerializerOptions
{
WriteIndented = true,
});
}
The default JSON formatters are based on System.Text.Json
. Support for Newtonsoft.Json
based formatters and features is available by installing the Microsoft.AspNetCore.Mvc.NewtonsoftJson
NuGet package and configuring it in Startup.ConfigureServices
.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson();
}
In the preceding code, the call to AddNewtonsoftJson
configures the following Web API, MVC, and Razor Pages features to use Newtonsoft.Json
:
Some features may not work well with System.Text.Json
-based formatters and require a reference to the Newtonsoft.Json
-based formatters. Continue using the Newtonsoft.Json
-based formatters when the app:
Newtonsoft.Json
attributes. For example, [JsonProperty]
or [JsonIgnore]
.Newtonsoft.Json
provides.Features for the Newtonsoft.Json
-based formatters can be configured using 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());
});
Output serialization options, on a per-action basis, can be configured using JsonResult
. For example:
public IActionResult Get()
{
return Json(model, new JsonSerializerSettings
{
Formatting = Formatting.Indented,
});
}
To restrict the response formats, apply the [Produces]
filter. Like most Filters, [Produces]
can be applied at the action, controller, or global scope:
[ApiController]
[Route("[controller]")]
[Produces("application/json")]
public class WeatherForecastController : ControllerBase
{
The preceding [Produces]
filter:
For more information, see Filters.
Some special cases are implemented using built-in formatters. By default, string
return types are formatted as text/plain (text/html if requested via the Accept
header). This behavior can be deleted by removing the StringOutputFormatter. Formatters are removed in the ConfigureServices
method. Actions that have a model object return type return 204 No Content
when returning null
. This behavior can be deleted by removing the HttpNoContentOutputFormatter. The following code removes the StringOutputFormatter
and HttpNoContentOutputFormatter
.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
// requires using Microsoft.AspNetCore.Mvc.Formatters;
options.OutputFormatters.RemoveType<StringOutputFormatter>();
options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
});
}
Without the StringOutputFormatter
, the built-in JSON formatter formats string
return types. If the built-in JSON formatter is removed and an XML formatter is available, the XML formatter formats string
return types. Otherwise, string
return types return 406 Not Acceptable
.
Without the HttpNoContentOutputFormatter
, null objects are formatted using the configured formatter. For example:
null
.xsi:nil="true"
set.Clients can request a particular format as part of the URL, for example:
The mapping from request path should be specified in the route the API is using. For example:
[Route("api/[controller]")]
[ApiController]
[FormatFilter]
public class ProductsController : ControllerBase
{
[HttpGet("{id}.{format?}")]
public Product Get(int id)
{
The preceding route allows the requested format to be specified as an optional file extension. The [FormatFilter]
attribute checks for the existence of the format value in the RouteData
and maps the response format to the appropriate formatter when the response is created.
Route | Formatter |
---|---|
/api/products/5 |
The default output formatter |
/api/products/5.json |
The JSON formatter (if configured) |
/api/products/5.xml |
The XML formatter (if configured) |
ASP.NET Core MVC supports formatting response data, using specified formats or in response to a client's request.
Some action result types are specific to a particular format, such as JsonResult and ContentResult. Actions can return results that always use a specified format, ignoring a client's request for a different format. For example, returning JsonResult
returns JSON-formatted data and returning ContentResult
returns plain-text-formatted string data.
An action isn't required to return any specific type. ASP.NET Core supports any object return value. Results from actions that return objects that aren't IActionResult types are serialized using the appropriate IOutputFormatter implementation. For more information, see Controller action return types in ASP.NET Core web API.
By default, the built-in helper method ControllerBase.Ok returns JSON-formatted data:
[HttpGet]
public IActionResult Get()
=> Ok(_todoItemStore.GetList());
The sample code returns a list of todo items. Using the F12 browser developer tools or http-repl with the previous code displays:
application/json; charset=utf-8
.Accept
header. The Accept
header is ignored by the preceding code.To return plain text formatted data, use ContentResult and the Content helper:
[HttpGet("Version")]
public ContentResult GetVersion()
=> Content("v1.0.0");
In the preceding code, the Content-Type
returned is text/plain
.
For actions with multiple return types, return IActionResult
. For example, when returning different HTTP status codes based on the result of the operation.
Content negotiation occurs when the client specifies an Accept header. The default format used by ASP.NET Core is JSON. Content negotiation is:
ObjectResult
.When a model type is returned, the return type is ObjectResult
.
The following action method uses the Ok
and NotFound
helper methods:
[HttpGet("{id:long}")]
public IActionResult GetById(long id)
{
var todo = _todoItemStore.GetById(id);
if (todo is null)
{
return NotFound();
}
return Ok(todo);
}
By default, ASP.NET Core supports the following media types:
application/json
text/json
text/plain
Tools such as Fiddler or http-repl can set the Accept
request header to specify the return format. When the Accept
header contains a type the server supports, that type is returned. The next section shows how to add additional formatters.
Controller actions can return POCOs (Plain Old CLR Objects). When a POCO is returned, the runtime automatically creates an ObjectResult
that wraps the object. The client gets the formatted serialized object. If the object being returned is null
, a 204 No Content
response is returned.
The following example returns an object type:
[HttpGet("{id:long}")]
public TodoItem? GetById(long id)
=> _todoItemStore.GetById(id);
In the preceding code, a request for a valid todo item returns a 200 OK
response. A request for an invalid todo item returns a 204 No Content
response.
Content negotiation takes place when an Accept
header appears in the request. When a request contains an accept header, ASP.NET Core:
If no formatter is found that can satisfy the client's request, ASP.NET Core:
406 Not Acceptable
if MvcOptions.ReturnHttpNotAcceptable is set to true
, or -If no formatter is configured for the requested format, the first formatter that can format the object is used. If no Accept
header appears in the request:
If the Accept header contains */*
, the Header is ignored unless RespectBrowserAcceptHeader
is set to true on MvcOptions.
Unlike typical API clients, web browsers supply Accept
headers. Web browsers specify many formats, including wildcards. By default, when the framework detects that the request is coming from a browser:
Accept
header is ignored.This approach provides a more consistent experience across browsers when consuming APIs.
To configure an app to respect browser accept headers, set the RespectBrowserAcceptHeader property to true
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
options.RespectBrowserAcceptHeader = true;
});
Apps that need to support extra formats can add the appropriate NuGet packages and configure support. There are separate formatters for input and output. Input formatters are used by Model Binding. Output formatters are used to format responses. For information on creating a custom formatter, see Custom Formatters.
To configure XML formatters implemented using XmlSerializer, call AddXmlSerializerFormatters:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddXmlSerializerFormatters();
When using the preceding code, controller methods return the appropriate format based on the request's Accept
header.
To configure features for the System.Text.Json
-based formatters, use Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. The following highlighted code configures PascalCase formatting instead of the default camelCase formatting:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = null;
});
To configure output serialization options for specific actions, use JsonResult. For example:
[HttpGet]
public IActionResult Get()
=> new JsonResult(
_todoItemStore.GetList(),
new JsonSerializerOptions { PropertyNamingPolicy = null });
The default JSON formatters use System.Text.Json
. To use the Newtonsoft.Json
-based formatters, install the Microsoft.AspNetCore.Mvc.NewtonsoftJson
NuGet package and configure it in Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddNewtonsoftJson();
In the preceding code, the call to AddNewtonsoftJson
configures the following Web API, MVC, and Razor Pages features to use Newtonsoft.Json
:
Some features may not work well with System.Text.Json
-based formatters and require a reference to the Newtonsoft.Json
-based formatters. Continue using the Newtonsoft.Json
-based formatters when the app:
Newtonsoft.Json
attributes. For example, [JsonProperty]
or [JsonIgnore]
.Newtonsoft.Json
provides.To configure features for the Newtonsoft.Json
-based formatters, use SerializerSettings:
builder.Services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
To configure output serialization options for specific actions, use JsonResult
. For example:
[HttpGet]
public IActionResult GetNewtonsoftJson()
=> new JsonResult(
_todoItemStore.GetList(),
new JsonSerializerSettings { ContractResolver = new DefaultContractResolver() });
The following action method calls ControllerBase.Problem to create a ProblemDetails response:
[HttpGet("Error")]
public IActionResult GetError()
=> Problem("Something went wrong.");
A ProblemDetails
response is always camelCase, even when the app sets the format to PascalCase. ProblemDetails
follows RFC 7807, which specifies lowercase.
When the [ApiController]
attribute is applied to a controller class, the controller creates a ValidationProblemDetails response when Model Validation fails. This response includes a dictionary that uses the model's property names as error keys, unchanged. For example, the following model includes a single property that requires validation:
public class SampleModel
{
[Range(1, 10)]
public int Value { get; set; }
}
By default, the ValidationProblemDetails
response returned when the Value
property is invalid uses an error key of Value
, as shown in the following example:
{
"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."
]
}
}
To format the property names used as error keys, add an implementation of IMetadataDetailsProvider to the MvcOptions.ModelMetadataDetailsProviders collection. The following example adds a System.Text.Json
-based implementation, SystemTextJsonValidationMetadataProvider
, which formats property names as camelCase by default:
builder.Services.AddControllers();
builder.Services.Configure<MvcOptions>(options =>
{
options.ModelMetadataDetailsProviders.Add(
new SystemTextJsonValidationMetadataProvider());
});
SystemTextJsonValidationMetadataProvider
also accepts an implementation of JsonNamingPolicy in its constructor, which specifies a custom naming policy for formatting property names.
To set a custom name for a property within a model, use the [JsonPropertyName] attribute on the property:
public class SampleModel
{
[Range(1, 10)]
[JsonPropertyName("sampleValue")]
public int Value { get; set; }
}
The ValidationProblemDetails
response returned for the preceding model when the Value
property is invalid uses an error key of sampleValue
, as shown in the following example:
{
"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."
]
}
}
To format the ValidationProblemDetails
response using Newtonsoft.Json
, use NewtonsoftJsonValidationMetadataProvider
:
builder.Services.AddControllers()
.AddNewtonsoftJson();
builder.Services.Configure<MvcOptions>(options =>
{
options.ModelMetadataDetailsProviders.Add(
new NewtonsoftJsonValidationMetadataProvider());
});
By default, NewtonsoftJsonValidationMetadataProvider
formats property names as camelCase. NewtonsoftJsonValidationMetadataProvider
also accepts an implementation of NamingPolicy
in its constructor, which specifies a custom naming policy for formatting property names. To set a custom name for a property within a model, use the [JsonProperty]
attribute.
To restrict the response formats, apply the [Produces]
filter. Like most Filters, [Produces]
can be applied at the action, controller, or global scope:
[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class TodoItemsController : ControllerBase
The preceding [Produces]
filter:
For more information, see Filters.
Some special cases are implemented using built-in formatters. By default, string
return types are formatted as text/plain (text/html if requested via the Accept
header). This behavior can be deleted by removing the StringOutputFormatter. Formatters are removed in Program.cs
. Actions that have a model object return type return 204 No Content
when returning null
. This behavior can be deleted by removing the HttpNoContentOutputFormatter. The following code removes the StringOutputFormatter
and HttpNoContentOutputFormatter
.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
// using Microsoft.AspNetCore.Mvc.Formatters;
options.OutputFormatters.RemoveType<StringOutputFormatter>();
options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
});
Without the StringOutputFormatter
, the built-in JSON formatter formats string
return types. If the built-in JSON formatter is removed and an XML formatter is available, the XML formatter formats string
return types. Otherwise, string
return types return 406 Not Acceptable
.
Without the HttpNoContentOutputFormatter
, null objects are formatted using the configured formatter. For example:
null
.xsi:nil="true"
set.Clients can request a particular format as part of the URL, for example:
The mapping from request path should be specified in the route the API is using. For example:
[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);
The preceding route allows the requested format to be specified using an optional file extension. The [FormatFilter]
attribute checks for the existence of the format value in the RouteData
and maps the response format to the appropriate formatter when the response is created.
Route | Formatter |
---|---|
/api/todoitems/5 |
The default output formatter |
/api/todoitems/5.json |
The JSON formatter (if configured) |
/api/todoitems/5.xml |
The XML formatter (if configured) |
Built-in features provide a limited range of polymorphic serialization but no support for deserialization at all. Deserialization requires a custom converter. See Polymorphic deserialization for a complete sample of polymorphic deserialization.
ASP.NET Core feedback
ASP.NET Core is an open source project. Select a link to provide feedback:
Training
Module
Render API responses in ASP.NET Core Razor Pages - Training
Render API responses in ASP.NET Core Razor Pages