Форматирование данных отклика в веб-API ASP.NET CoreFormat response data in ASP.NET Core Web API

Авторы: Рик Андерсон (Rick Anderson) и Стив Смит (Steve Smith)By Rick Anderson and Steve Smith

Приложение MVC ASP.NET Core поддерживает форматирование данных ответа.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)

Результаты действий для конкретного форматаFormat-specific Action Results

Некоторые типы результатов действий характерны для определенного формата, например JsonResult и ContentResult.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. Например, при возврате JsonResult возвращаются данные в формате JSON.For example, returning JsonResult returns JSON-formatted data. При возврате ContentResult или строки возвращаются строковые данные в формате обычного текста.Returning ContentResult or a string returns plain-text-formatted string data.

Действие не должно возвращать данные конкретного типа.An action isn't required to return any specific type. ASP.NET Core поддерживает любое возвращаемое значение объекта.ASP.NET Core supports any object return value. Результаты из действий, возвращающих объекты, которые не являются типами IActionResult, сериализуются с помощью соответствующей реализации IOutputFormatter.Results from actions that return objects that are not IActionResult types are serialized using the appropriate IOutputFormatter implementation. Дополнительные сведения см. в разделе Типы возвращаемых значений действий контроллера в веб-API ASP.NET Core.For more information, see Типы возвращаемых значений действий контроллера в веб-API ASP.NET Core.

Встроенный вспомогательный метод Ok возвращает данные в формате JSON: [!code-csharp]The built-in helper method Ok returns JSON-formatted data: [!code-csharp]

Скачанный пример возвращает список авторов.The sample download returns the list of authors. При использовании средств разработчика в браузере (F12) или Postman с предыдущим кодом:Using the F12 browser developer tools or Postman with the previous code:

  • Отобразится заголовок ответа, содержащий content-type: application/json; charset=utf-8.The response header containing content-type: application/json; charset=utf-8 is displayed.
  • Отобразятся заголовки запросов.The request headers are displayed. Например, заголовок Accept.For example, the Accept header. Приведенный выше код игнорирует заголовок Accept.The Accept header is ignored by the preceding code.

Чтобы возвратить данные в формате обычного текста, используйте ContentResult и вспомогательный метод Content:To return plain text formatted data, use ContentResult and the Content helper:

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

В приведенном выше коде возвращаемым Content-Type является text/plain.In the preceding code, the Content-Type returned is text/plain. При возврате строки возвращается Content-Type со значением 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";
}

Для действий с несколькими возвращаемыми типами возвращается значение IActionResult.For actions with multiple return types, return IActionResult. Например, возвращаются различные коды состояния HTTP на основе результатов выполненных операций.For example, returning different HTTP status codes based on the result of operations performed.

Согласование содержимогоContent negotiation

Согласование содержимого происходит, когда клиент задает заголовок Accept.Content negotiation occurs when the client specifies an Accept header. Для ASP.NET Core по умолчанию используется формат JSON.The default format used by ASP.NET Core is JSON. Согласование содержимого:Content negotiation is:

  • реализуется с помощью ObjectResult;Implemented by ObjectResult.
  • встроено в результаты действия с определенным кодом состояния, возвращаемые из вспомогательных методов;Built into the status code-specific action results returned from the helper methods. вспомогательные методы результатов действия основаны на ObjectResult;The action results helper methods are based on ObjectResult.

при возврате типа модели возвращаемым типом является ObjectResult.When a model type is returned, the return type is ObjectResult.

Следующий метод действия использует вспомогательные методы Ok и NotFound:The following action method uses the Ok and NotFound helper methods:

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

По умолчанию ASP.NET Core поддерживает типы мультимедиа application/json, text/json и text/plain.By default, ASP.NET Core supports application/json, text/json, and text/plain media types. Средства, такие как Fiddler или Postman, могут установить заголовок запроса Accept, чтобы указать формат возвращаемого значения.Tools such as Fiddler or Postman can set the Accept request header to specify the return format. Если заголовок Accept содержит тип, который поддерживается сервером, возвращается этот тип.When the Accept header contains a type the server supports, that type is returned. Сведения о добавлении дополнительных форматировщиков приведены в следующем разделе.The next section shows how to add additional formatters.

Действия контроллера могут возвращать POCO (простые объекты CLR).Controller actions can return POCOs (Plain Old CLR Objects). При возвращении POCO среда выполнения автоматически создает ObjectResult, который генерирует оболочку объекта.When a POCO is returned, the runtime automatically creates an ObjectResult that wraps the object. Клиент получает отформатированный сериализованный объект.The client gets the formatted serialized object. Если возвращаемый объект имеет значение null, возвращается ответ 204 No Content.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);
}

В приведенном выше коде запрос допустимого псевдонима автора получает ответ 200 OK с данными об авторе.In the preceding code, a request for a valid author alias returns a 200 OK response with the author's data. Запрос недопустимого псевдонима возвращает ответ 204 No Content.A request for an invalid alias returns a 204 No Content response.

Заголовок AcceptThe Accept header

Согласование содержимого выполняется только при наличии в запросе заголовка Accept.Content negotiation takes place when an Accept header appears in the request. Если запрос содержит заголовок Accept, ASP.NET Core:When a request contains an accept header, ASP.NET Core:

  • перечисляет типы мультимедиа в заголовке Accept в порядке предпочтения;Enumerates the media types in the accept header in preference order.
  • пытается найти форматировщик, который может создать ответ в одном из указанных форматов.Tries to find a formatter that can produce a response in one of the formats specified.

Если форматировщик, который может удовлетворить запрос клиента, не найден, ASP.NET Core:If no formatter is found that can satisfy the client's request, ASP.NET Core:

  • возвращает значение 406 Not Acceptable, если MvcOptions задано, или:Returns 406 Not Acceptable if MvcOptions has been set, or -
  • пытается найти первый форматировщик, который может создать ответ.Tries to find the first formatter that can produce a response.

Если форматировщик, обеспечивающий требуемый формат, не настроен, используется первый форматировщик, способный отформатировать данный объект.If no formatter is configured for the requested format, the first formatter that can format the object is used. Если в запросе не отображается заголовок Accept:If no Accept header appears in the request:

  • Для сериализации ответа используется первый форматировщик, который может работать с объектом.The first formatter that can handle the object is used to serialize the response.
  • Согласование не выполняется.There isn't any negotiation taking place. Сервер определяет возвращаемый формат.The server is determining what format to return.

Если заголовок Accept содержит */*, он игнорируется, если только RespectBrowserAcceptHeader не имеет значение true в MvcOptions.If the Accept header contains */*, the Header is ignored unless RespectBrowserAcceptHeader is set to true on MvcOptions.

Браузеры и согласование содержимогоBrowsers and content negotiation

В отличие от обычных клиентов API, веб-браузеры предоставляют заголовки Accept.Unlike typical API clients, web browsers supply Accept headers. Веб-браузер определяет множество форматов, включая подстановочные знаки.Web browser specify many formats, including wildcards. Если платформа обнаруживает, что запрос поступает из браузера, по умолчанию выполняется следующее:By default, when the framework detects that the request is coming from a browser:

  • Заголовок Accept игнорируется.The Accept header is ignored.
  • Содержимое возвращается в формате JSON, если не указано иначе.The content is returned in JSON, unless otherwise configured.

Это обеспечивает более согласованное взаимодействие между браузерами при использовании API.This provides a more consistent experience across browsers when consuming APIs.

Чтобы настроить приложение для учета заголовков Accept в браузере, установите для параметра RespectBrowserAcceptHeader значение true: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
    });
}
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.RespectBrowserAcceptHeader = true; // false by default
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

Настройка форматировщиковConfigure formatters

В приложениях, которым требуется поддержка дополнительных форматов, можно добавлять соответствующие пакеты NuGet и настраивать поддержку.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. Сведения о создании пользовательского форматировщика см. в статье Пользовательские модули форматирования для веб-API в ASP.NET Core.For information on creating a custom formatter, see Custom Formatters.

Добавление поддержки формата XMLAdd XML format support

Форматировщики XML, реализованные с помощью XmlSerializer, можно настроить путем вызова AddXmlSerializerFormatters:XML formatters implemented using XmlSerializer are configured by calling AddXmlSerializerFormatters:

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

Приведенный выше код сериализует результаты с помощью XmlSerializer.The preceding code serializes results using XmlSerializer.

При использовании приведенного выше кода методы контроллера возвращают соответствующий формат на основе заголовка Accept запроса.When using the preceding code, controller methods return the appropriate format based on the request's Accept header.

Настройка форматировщиков на основе System.Text.JsonConfigure System.Text.Json-based formatters

Функции для форматировщиков на основе System.Text.Json можно настроить с помощью Microsoft.AspNetCore.Mvc.JsonOptions.SerializerOptions.Features for the System.Text.Json-based formatters can be configured using Microsoft.AspNetCore.Mvc.JsonOptions.SerializerOptions.

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

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

Параметры сериализации выходных данных для отдельных действий можно настроить с помощью JsonResult.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,
    });
}

Добавление поддержки формата JSON на основе Newtonsoft.JsonAdd Newtonsoft.Json-based JSON format support

До выпуска версии ASP.NET Core 3.0 по умолчанию использовались форматировщики JSON, реализованные с помощью пакета Newtonsoft.Json.Prior to ASP.NET Core 3.0, the default used JSON formatters implemented using the Newtonsoft.Json package. В ASP.NET Core 3.0 или более поздней версии форматировщики JSON по умолчанию основаны на System.Text.Json.In ASP.NET Core 3.0 or later, the default JSON formatters are based on System.Text.Json. Поддержка Newtonsoft.Json модулей форматирования и функций на основе данных доступна путем установки Microsoft.AspNetCore.Mvc.NewtonsoftJson пакета NuGet и его настройки в Startup.ConfigureServices .Support for Newtonsoft.Json based formatters and features is available by installing the Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet package and configuring it in Startup.ConfigureServices.

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

Возможно, некоторые функции не будут оптимально работать с форматировщиками на основе System.Text.Json и будут требовать ссылки на форматировщики на основе Newtonsoft.Json.Some features may not work well with System.Text.Json-based formatters and require a reference to the Newtonsoft.Json-based formatters. Продолжайте использовать форматировщики на основе Newtonsoft.Json, если приложение:Continue using the Newtonsoft.Json-based formatters if the app:

  • Использует атрибут Newtonsoft.Json.Uses Newtonsoft.Json attributes. Например, [JsonProperty] или [JsonIgnore].For example, [JsonProperty] or [JsonIgnore].
  • Настраивает параметры сериализации.Customizes the serialization settings.
  • Зависит от функций, предоставляемых Newtonsoft.Json.Relies on features that Newtonsoft.Json provides.
  • Настраивается Microsoft.AspNetCore.Mvc.JsonResult.SerializerSettings.Configures Microsoft.AspNetCore.Mvc.JsonResult.SerializerSettings. В ASP.NET Core более ранних версий, чем версия 3.0, JsonResult.SerializerSettings принимает экземпляр JsonSerializerSettings, который относится к Newtonsoft.Json.Prior to ASP.NET Core 3.0, JsonResult.SerializerSettings accepts an instance of JsonSerializerSettings that is specific to Newtonsoft.Json.
  • Создается документация OpenAPI.Generates OpenAPI documentation.

Функции для форматировщиков на основе Newtonsoft.Json можно настроить с помощью Microsoft.AspNetCore.Mvc.MvcNewtonsoftJsonOptions.SerializerSettings: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());
});

Параметры сериализации выходных данных для отдельных действий можно настроить с помощью JsonResult.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,
    });
}

Добавление поддержки формата XMLAdd XML format support

Для форматирования XML требуется пакет NuGet Microsoft.AspNetCore.Mvc.Formatters.Xml.XML formatting requires the Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet package.

Форматировщики XML, реализованные с помощью XmlSerializer, можно настроить путем вызова AddXmlSerializerFormatters:XML formatters implemented using XmlSerializer are configured by calling AddXmlSerializerFormatters:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
        .AddXmlSerializerFormatters();
}

Приведенный выше код сериализует результаты с помощью XmlSerializer.The preceding code serializes results using XmlSerializer.

При использовании приведенного выше кода методы контроллера должны возвращать соответствующий формат на основе заголовка Accept запроса.When using the preceding code, controller methods should return the appropriate format based on the request's Accept header.

Указание форматаSpecify a format

Чтобы ограничить форматы ответа, примените [Produces] фильтр.To restrict the response formats, apply the [Produces] filter. Как и большинство фильтров, [Produces] можно применить к действию, контроллеру или глобальной области:Like most Filters, [Produces] can be applied at the action, controller, or global scope:

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

Предыдущий [Produces] Фильтр:The preceding [Produces] filter:

  • Заставляет все действия в контроллере возвращать ответы в формате JSON.Forces all actions within the controller to return JSON-formatted responses.
  • Если другие форматировщики настроены и клиент указывает другой формат, возвращается JSON.If other formatters are configured and the client specifies a different format, JSON is returned.

Дополнительные сведения см. в статье Фильтры в ASP.NET Core.For more information, see Filters.

Специальные форматировщикиSpecial case formatters

Встроенные модули форматирования реализуют некоторые специальные возможности.Some special cases are implemented using built-in formatters. По умолчанию типы возвращаемых значений string форматируются как text/plain (text/html, если того требует заголовок Accept).By default, string return types are formatted as text/plain (text/html if requested via the Accept header). Это поведение можно отключить, удалив StringOutputFormatter.This behavior can be deleted by removing the StringOutputFormatter. Форматировщики удаляются в методе ConfigureServices.Formatters are removed in the ConfigureServices method. Действия, у которых типом возвращаемого объекта является модель, возвращают ответ 204 No Content при возврате значения null.Actions that have a model object return type return 204 No Content when returning null. Это поведение можно отключить, удалив HttpNoContentOutputFormatter.This behavior can be deleted by removing the HttpNoContentOutputFormatter. Приведенный ниже код удаляет StringOutputFormatter и 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>();
    });
}
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        // requires using Microsoft.AspNetCore.Mvc.Formatters;
        options.OutputFormatters.RemoveType<StringOutputFormatter>();
        options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

Без StringOutputFormatter, встроенный модуль форматирования JSON форматирует типы возвращаемого значения string.Without the StringOutputFormatter, the built-in JSON formatter formats string return types. Если встроенный модуль форматирования JSON удален и доступен модуль форматирования XML, то типы возвращаемого значения string форматирует модуль форматирования XML.If the built-in JSON formatter is removed and an XML formatter is available, the XML formatter formats string return types. В противном случае, string типы возвращаемого значения возвращают 406 Not Acceptable.Otherwise, string return types return 406 Not Acceptable.

Без HttpNoContentOutputFormatter объекты со значением null форматируются с помощью настроенного модуля форматирования.Without the HttpNoContentOutputFormatter, null objects are formatted using the configured formatter. Пример:For example:

  • Форматировщик JSON возвращает ответ с текстом null.The JSON formatter returns a response with a body of null.
  • Форматировщик XML возвращает пустой XML-элемент с атрибутом xsi:nil="true".The XML formatter returns an empty XML element with the attribute xsi:nil="true" set.

Сопоставления URL-адреса для формата ответаResponse format URL mappings

Клиенты могут запрашивать определенный формат как часть URL-адреса, например:Clients can request a particular format as part of the URL, for example:

  • В строке запроса или в части пути.In the query string or part of the path.
  • С использованием расширения файла конкретного формата, такого как XML или JSON.By using a format-specific file extension such as .xml or .json.

Сопоставление из пути запроса должно быть указано в маршруте, используемом API.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. [FormatFilter]Атрибут проверяет наличие значения формата в RouteData и сопоставляет формат ответа с соответствующим модулем форматирования при создании ответа.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 FormatterFormatter
/api/products/5 Модуль форматирования вывода по умолчаниюThe default output formatter
/api/products/5.json Модуль форматирования JSON (если настроен)The JSON formatter (if configured)
/api/products/5.xml Модуль форматирования XML (если настроен)The XML formatter (if configured)