Udostępnij za pośrednictwem


Formatowanie danych odpowiedzi w internetowym interfejsie API platformy ASP.NET Core

ASP.NET Core MVC obsługuje formatowanie danych odpowiedzi przy użyciu określonych formatów lub w odpowiedzi na żądanie klienta.

Wyniki akcji specyficzne dla formatu

Niektóre typy wyników akcji są specyficzne dla określonego formatu, takiego jak JsonResult i ContentResult. Akcje mogą zwracać wyniki, które zawsze używają określonego formatu, ignorując żądanie klienta dla innego formatu. Na przykład zwrócenie JsonResult zwraca dane sformatowane w formacie JSON, a zwrócenie ContentResult zwraca dane ciągów sformatowane w formacie zwykłego tekstu.

Nie jest wymagane, aby akcja zwracała konkretny typ. ASP.NET Core obsługuje dowolną wartość zwracaną przez obiekt. Wyniki akcji, które zwracają obiekty niebędące typami IActionResult, są serializowane przy użyciu odpowiedniej implementacji IOutputFormatter. Aby uzyskać więcej informacji, zobacz Typy zwracane przez akcje kontrolera w ASP.NET Core Web API.

Domyślnie wbudowana metoda ControllerBase.Ok pomocnika zwraca dane w formacie JSON:

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

Przykładowy kod zwraca listę zadań do wykonania. Za pomocą narzędzi deweloperskich przeglądarki F12 lub http-repl z poprzednim kodem wyświetla się:

  • Nagłówek odpowiedzi zawierający typ zawartości:application/json; charset=utf-8.
  • Nagłówki żądania. Na przykład nagłówka Accept. Nagłówek Accept jest ignorowany przez poprzedni kod.

Aby zwrócić dane sformatowane w postaci zwykłego tekstu, skorzystaj z polecenia ContentResult i pomocnika Content.

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

W poprzednim kodzie Content-Type zwracany jest text/plain.

W przypadku akcji z wieloma typami zwracanymi zwróć wartość IActionResult. Na przykład podczas zwracania różnych kodów stanu HTTP na podstawie wyniku operacji.

Negocjowanie zawartości

Negocjowanie zawartości występuje, gdy klient określa nagłówek Accept. Domyślny format używany przez ASP.NET Core to JSON. Negocjacja zawartości jest:

  • Zaimplementowane przez program ObjectResult.
  • Zakodowane w wynikach działań specyficznych dla kodu statusu zwracanych z metod pomocniczych. Metody pomocnicze wyników akcji są oparte na ObjectResult.

Gdy zwracany jest typ modelu, zwracany typ to ObjectResult.

Poniższa metoda akcji używa metod pomocniczych Ok i NotFound.

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

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

    return Ok(todo);
}

Domyślnie ASP.NET Core obsługuje następujące typy multimediów:

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

Narzędzia, takie jak Fiddler lub curl, mogą ustawić Accept nagłówek żądania, aby określić format zwracany. Accept Gdy nagłówek zawiera typ, który obsługuje serwer, zwracany jest ten typ. W następnej sekcji pokazano, jak dodać dodatkowe formatery.

Akcje kontrolera mogą zwracać obiekty POC (zwykłe stare obiekty CLR). Po zwróceniu POCO, środowisko uruchomieniowe automatycznie tworzy ObjectResult obiekt, który zawija ten obiekt. Klient pobiera sformatowany obiekt serializowany. Jeśli zwracanym obiektem jest null, to zwracana jest odpowiedź 204 No Content.

Poniższy przykład zwraca typ obiektu:

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

W poprzednim kodzie żądanie prawidłowego elementu zadania do wykonania zwraca 200 OK odpowiedź. Żądanie nieprawidłowego elementu todo zwraca 204 No Content odpowiedź.

Nagłówek Accept

Negocjowanie zawartości odbywa się po Accept wyświetleniu nagłówka w żądaniu. Gdy żądanie zawiera nagłówek Accept, ASP.NET Core:

  • Wylicza typy multimediów w nagłówku accept w kolejności preferencji.
  • Próbuje znaleźć formater, który może wygenerować odpowiedź w jednym z określonych formatów.

Jeśli nie znaleziono programu formatującego, który może spełnić żądanie klienta, ASP.NET Core:

  • Zwraca 406 Not Acceptable, jeśli MvcOptions.ReturnHttpNotAcceptable jest ustawione na true lub —
  • Próbuje znaleźć pierwszy formater, który może wygenerować odpowiedź.

Jeśli dla żądanego formatu nie skonfigurowano żadnego formatowania, zostanie użyty pierwszy formater, który może sformatować obiekt. Jeśli w żądaniu nie pojawi się żaden Accept nagłówek:

  • Pierwszy formater, który może obsłużyć obiekt, jest używany do serializacji odpowiedzi.
  • Nie ma żadnych negocjacji. Serwer określa, jaki format ma być zwracany.

Jeśli nagłówek Accept zawiera */*, nagłówek jest ignorowany, chyba że RespectBrowserAcceptHeader ustawiono na wartość true dla elementu MvcOptions.

Przeglądarki i negocjacje zawartości

W przeciwieństwie do typowych klientów interfejsu API przeglądarki internetowe dostarczają Accept nagłówki. Przeglądarki sieci Web określają wiele formatów, w tym symbole wieloznaczne. Domyślnie gdy platforma wykryje, że żądanie pochodzi z przeglądarki:

  • Nagłówek Accept jest ignorowany.
  • Zawartość jest zwracana przy użyciu pierwszego zarejestrowanego formatera danych wyjściowych, który może obsługiwać typ odpowiedzi, chyba że skonfigurowano inaczej.

Takie podejście zapewnia bardziej spójne środowisko we wszystkich przeglądarkach w przypadku korzystania z interfejsów API.

Aby skonfigurować aplikację tak, aby przestrzegała nagłówków akceptowanych przez przeglądarkę, ustaw właściwość RespectBrowserAcceptHeader na true.

var builder = WebApplication.CreateBuilder(args);

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

Konfigurowanie formaterów

Aplikacje, które muszą obsługiwać dodatkowe formaty, mogą dodawać odpowiednie pakiety NuGet i konfigurować obsługę. Istnieją oddzielne formatery dla danych wejściowych i wyjściowych. Formatery danych wejściowych są używane przez Model Binding. Formatery danych wyjściowych służą do formatowania odpowiedzi. Aby uzyskać informacje na temat tworzenia niestandardowego modułu formatującego, zobacz Niestandardowe formatery.

Dodanie obsługi formatu XML

Aby skonfigurować formatery XML zaimplementowane przy użyciu metody XmlSerializer, wywołaj metodę AddXmlSerializerFormatters:

var builder = WebApplication.CreateBuilder(args);

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

W przypadku używania poprzedniego kodu metody kontrolera zwracają odpowiedni format na podstawie nagłówka Accept żądania.

Konfiguracja formaterów opartych na System.Text.Json

Aby skonfigurować funkcje dla formaterów opartych na System.Text.Json protokole, użyj polecenia Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. Poniższy wyróżniony kod konfiguruje formatowanie PascalCase zamiast domyślnego formatowania camelCase:

var builder = WebApplication.CreateBuilder(args);

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

Następująca metoda akcji wywołuje ControllerBase.Problem w celu utworzenia ProblemDetails odpowiedzi.

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

ProblemDetails Odpowiedź jest zawsze camelCase, nawet jeśli aplikacja ustawia format na PascalCase. ProblemDetails program jest zgodny z specyfikacją RFC 7807, która określa małe litery.

Aby skonfigurować opcje serializacji danych wyjściowych dla określonych akcji, użyj polecenia JsonResult. Przykład:

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

Obsługa formatu JSON opartego na Newtonsoft.Json

Domyślne formatery JSON wykorzystują System.Text.Json. Aby użyć formaterów opartych na Newtonsoft.Json, zainstaluj pakiet NuGet Microsoft.AspNetCore.Mvc.NewtonsoftJson i skonfiguruj go w Program.cs.

var builder = WebApplication.CreateBuilder(args);

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

W poprzednim kodzie wywołanie AddNewtonsoftJson konfiguruje następujące funkcje internetowego interfejsu API, MVC i Razor stron do użycia Newtonsoft.Json.

Niektóre funkcje mogą nie działać dobrze z formaterami System.Text.Jsonopartymi na protokole i wymagają odwołania do Newtonsoft.Jsonformaterów opartych na protokole. Kontynuuj korzystanie z formaterów opartych na Newtonsoft.Json, gdy aplikacja:

  • Używa Newtonsoft.Json atrybutów. Na przykład: [JsonProperty] lub [JsonIgnore].
  • Dostosowuje ustawienia serializacji.
  • Opiera się na funkcjach, które Newtonsoft.Json dostarcza.

Aby skonfigurować funkcje dla formaterów opartych na Newtonsoft.Json, użyj SerializerSettings:

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

Aby skonfigurować opcje serializacji danych wyjściowych dla określonych akcji, użyj polecenia JsonResult. Przykład:

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

Określanie formatu

Aby ograniczyć formaty odpowiedzi, zastosuj [Produces] filtr. Podobnie jak większość filtrów, [Produces] można zastosować do akcji, kontrolera lub zakresu globalnego:

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

Powyższy [Produces] filtr:

  • Wymusza wszystkie akcje w kontrolerze na zwracanie odpowiedzi w formacie JSON dla obiektów POCO (Plain Old CLR Objects) lub ObjectResult i ich typów pochodnych.
  • Zwracanie odpowiedzi sformatowanych w formacie JSON, nawet jeśli inne formatatory są skonfigurowane, a klient określa inny format.

Aby uzyskać więcej informacji, zobacz Filtry.

Specjalne formatery wielkości liter

Niektóre specjalne przypadki są implementowane przy użyciu wbudowanych formatatorów. Domyślnie string typy zwracane są formatowane jako tekst/plain (tekst/html, jeśli jest to wymagane za pośrednictwem nagłówka Accept). To zachowanie można usunąć, usuwając element StringOutputFormatter. Formatery są usuwane w pliku Program.cs. Akcje, które mają typ zwracanego obiektu modelu, zwracają 204 No Content gdy zwracają null. To zachowanie można usunąć, usuwając element HttpNoContentOutputFormatter. Poniższy kod usuwa elementy StringOutputFormatter i HttpNoContentOutputFormatter.

var builder = WebApplication.CreateBuilder(args);

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

StringOutputFormatterBez wbudowanego formatu string formatującego JSON zwraca typy. Jeśli wbudowany formater JSON zostanie usunięty, a formater XML jest dostępny, formater XML formatuje typy zwracane jako string. string W przeciwnym razie zwracane typy zwracają wartość 406 Not Acceptable.

Bez HttpNoContentOutputFormatter obiekty null są formatowane przy użyciu skonfigurowanego formatera. Przykład:

  • Formater JSON zwraca odpowiedź z treścią null.
  • Funkcja formatowania XML zwraca pusty element XML z zestawem atrybutów xsi:nil="true" .

Mapowanie adresów URL dla formatu odpowiedzi

Klienci mogą zażądać określonego formatu jako części adresu URL, na przykład:

  • W ciągu zapytania lub w części ścieżki.
  • Za pomocą rozszerzenia pliku specyficznego dla formatu, takiego jak .xml lub .json.

Mapowanie ścieżki żądania należy określić w trasie, z której korzysta interfejs API. Przykład:

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

Poprzednia trasa umożliwia określenie żądanego formatu przy użyciu opcjonalnego rozszerzenia pliku. Atrybut [FormatFilter] sprawdza, czy wartość formatu istnieje w RouteData i mapuje format odpowiedzi na odpowiedni formatator, gdy odpowiedź jest tworzona.

Route Formatter
/api/todoitems/5 Domyślny formater danych wyjściowych
/api/todoitems/5.json Formater JSON (jeśli został skonfigurowany)
/api/todoitems/5.xml Formater XML (jeśli został skonfigurowany)

Deserializacja polimorficzna

Wbudowane funkcje zapewniają ograniczony zakres serializacji polimorficznej, ale w ogóle nie obsługują deserializacji. Deserializacja wymaga niestandardowego konwertera. Zapoznaj się z deserializacją polimorficzną, aby uzyskać kompletny przykład deserializacji polimorficznej.

Dodatkowe zasoby

ASP.NET Core MVC obsługuje formatowanie danych odpowiedzi. Dane odpowiedzi można sformatować przy użyciu określonych formatów lub w odpowiedzi na żądany format klienta.

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Wyniki akcji specyficzne dla formatu

Niektóre typy wyników akcji są specyficzne dla określonego formatu, takiego jak JsonResult i ContentResult. Akcje mogą zwracać wyniki sformatowane w określonym formacie, niezależnie od preferencji klienta. Na przykład zwracanie JsonResult powoduje zwrócenie danych w formacie JSON. Zwracanie ContentResult lub ciągu zwraca dane sformatowane jako zwykły tekst.

Nie jest wymagane, aby akcja zwracała konkretny typ. ASP.NET Core obsługuje dowolną wartość zwracaną przez obiekt. Wyniki akcji, które zwracają obiekty niebędące typami IActionResult, są serializowane przy użyciu odpowiedniej implementacji IOutputFormatter. Aby uzyskać więcej informacji, zobacz Typy zwracane przez akcje kontrolera w ASP.NET Core Web API.

Wbudowana metoda Ok pomocnika zwraca dane sformatowane w formacie JSON:

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

Pobieranie przykładowe zwraca listę autorów. Używając narzędzi deweloperskich przeglądarki F12 lub http-repl w kontekście poprzedniego kodu:

  • Zostanie wyświetlony nagłówek odpowiedzi zawierający typ zawartości:application/json; charset=utf-8
  • Zostaną wyświetlone nagłówki żądania. Na przykład nagłówka Accept. Nagłówek Accept jest ignorowany przez poprzedni kod.

Aby zwrócić dane sformatowane w postaci zwykłego tekstu, użyj ContentResult oraz funkcji pomocniczej Content.

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

W poprzednim kodzie zwracana wartość Content-Type to text/plain. Zwrócenie ciągu daje Content-Type z text/plain:

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

W przypadku akcji z wieloma typami zwracanymi zwróć wartość IActionResult. Na przykład zwracanie różnych kodów stanu HTTP na podstawie wyniku wykonanych operacji.

Negocjowanie zawartości

Negocjowanie zawartości występuje, gdy klient określa nagłówek "Accept". Domyślny format używany przez ASP.NET Core to JSON. Negocjowanie zawartości jest:

  • Zaimplementowane przez program ObjectResult.
  • Wbudowane wyniki akcji specyficznej dla kodu stanu zwrócone z metod pomocnika. Metody pomocnika wyników akcji są oparte na ObjectResult.

Gdy zwracany jest typ modelu, zwracany typ to ObjectResult.

Poniższa metoda akcji używa metod pomocniczych Ok i 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);
}

Domyślnie platforma ASP.NET Core obsługuje application/jsontypy multimediów , text/jsoni text/plain . Narzędzia, takie jak Fiddler lub http-repl , mogą ustawić Accept nagłówek żądania, aby określić format zwracany. Accept Gdy nagłówek zawiera typ, który obsługuje serwer, zwracany jest ten typ. W następnej sekcji pokazano, jak dodać dodatkowe formatery.

Akcje kontrolera mogą zwracać obiekty POCO (zwykłe, proste obiekty CLR). Gdy zwracany jest POCO, środowisko uruchomieniowe automatycznie tworzy ObjectResult, które opakowuje obiekt. Klient pobiera sformatowany obiekt serializowany. Jeśli zwracany obiekt to null, zostanie zwrócona odpowiedź 204 No Content.

Zwracanie typu obiektu:

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

W poprzednim kodzie żądanie prawidłowego aliasu autora zwraca 200 OK odpowiedź z danymi autora. Żądanie nieprawidłowego aliasu zwraca 204 No Content odpowiedź.

Nagłówek Accept

Negocjowanie zawartości odbywa się, gdy nagłówek Accept pojawia się w żądaniu. Gdy żądanie zawiera nagłówek Accept, ASP.NET Core:

  • Wylicza typy multimediów w nagłówku accept w kolejności preferencji.
  • Próbuje znaleźć formater, który może wygenerować odpowiedź w jednym z określonych formatów.

Jeśli nie znaleziono programu formatującego, który może spełnić żądanie klienta, ASP.NET Core:

  • Zwraca 406 Not Acceptable, jeśli MvcOptions.ReturnHttpNotAcceptable ustawiono na true, lub -
  • Próbuje znaleźć formater, który jako pierwszy może wygenerować odpowiedź.

Jeśli dla żądanego formatu nie skonfigurowano żadnego formatowania, zostanie użyty pierwszy formater, który może sformatować obiekt. Jeśli żaden nagłówek Accept nie pojawi się w żądaniu:

  • Pierwszy formater, który może obsłużyć obiekt, jest używany do serializacji odpowiedzi.
  • Nie ma żadnych negocjacji. Serwer określa, jaki format ma być zwracany.

Jeśli nagłówek Accept zawiera */*, nagłówek jest ignorowany, chyba że RespectBrowserAcceptHeader ustawiono na true dla MvcOptions.

Przeglądarki i negocjacje zawartości

W przeciwieństwie do typowych klientów interfejsu API przeglądarki internetowe dostarczają Accept nagłówki. Przeglądarki sieci Web określają wiele formatów, w tym symbole wieloznaczne. Domyślnie gdy platforma wykryje, że żądanie pochodzi z przeglądarki:

  • Nagłówek Accept jest ignorowany.
  • Zawartość jest zwracana przy użyciu pierwszego zarejestrowanego formatera danych wyjściowych, który może obsługiwać typ odpowiedzi, chyba że skonfigurowano inaczej.

Takie podejście zapewnia bardziej spójne doświadczenie w przeglądarkach podczas korzystania z interfejsów API.

Aby skonfigurować aplikację do respektowania nagłówków 'accept' przeglądarki, ustaw wartość RespectBrowserAcceptHeadertrue:

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

Konfigurowanie formaterów

Aplikacje, które muszą obsługiwać dodatkowe formaty, mogą dodawać odpowiednie pakiety NuGet i konfigurować obsługę. Istnieją oddzielne formatery dla danych wejściowych i wyjściowych. Formatery danych wejściowych są używane przez Model Binding. Formatery danych wyjściowych służą do formatowania odpowiedzi. Aby uzyskać informacje na temat tworzenia niestandardowego modułu formatującego, zobacz Niestandardowe formatery.

Wsparcie dla formatu XML

Implementowane przy użyciu XmlSerializer formatery XML są konfigurowane przez wywołanie metody AddXmlSerializerFormatters:

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

Powyższy kod serializuje wyniki przy użyciu metody XmlSerializer.

W przypadku używania poprzedniego kodu metody kontrolera zwracają odpowiedni format na podstawie nagłówka Accept żądania.

Konfigurowanie formaterów bazujących na System.Text.Json

Funkcje dla formaterów opartych na System.Text.Json można skonfigurować za pomocą Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. Domyślne formatowanie to camelCase. Następujący fragment kodu ustawia formatowanie PascalCase.

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

Następująca metoda akcji wywołuje ControllerBase.Problem w celu utworzenia odpowiedzi ProblemDetails.

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

Z poprzednim kodem:

  • https://localhost:5001/WeatherForecast/temperature zwraca PascalCase.
  • https://localhost:5001/WeatherForecast/error zwraca camelCase. Odpowiedź na błąd jest zawsze camelCase, nawet jeśli aplikacja ustawia format na PascalCase. ProblemDetails jest zgodny z RFC 7807, który określa małe litery

Poniższy kod ustawia PascalCase i dodaje konwerter niestandardowy:

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

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

Opcje serializacji danych wyjściowych dla poszczególnych akcji można skonfigurować przy użyciu polecenia JsonResult. Przykład:

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

Dodaj obsługę formatu JSON opartego na Newtonsoft.Json

Domyślne formatery JSON są oparte na .System.Text.Json Obsługa formaterów i funkcji opartych na Newtonsoft.Json jest dostępna poprzez zainstalowanie pakietu NuGet Microsoft.AspNetCore.Mvc.NewtonsoftJson i skonfigurowanie go w Startup.ConfigureServices.

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

W poprzednim kodzie wywołanie AddNewtonsoftJson konfiguruje następujące funkcje Web API, MVC i Razor Pages do użycia Newtonsoft.Json:

Niektóre funkcje mogą nie działać dobrze z formaterami System.Text.Json i wymagają odwołania do formaterów Newtonsoft.Json. Kontynuuj korzystanie z formaterów opartych na Newtonsoft.Json, gdy aplikacja:

  • Używa Newtonsoft.Json atrybutów. Na przykład: [JsonProperty] lub [JsonIgnore].
  • Dostosowuje ustawienia serializacji.
  • Opiera się na funkcjach, które Newtonsoft.Json udostępnia.

Funkcje dla formaterów opartych na Newtonsoft.Json można skonfigurować za pomocą 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());
});

Opcje serializacji danych wyjściowych dla poszczególnych akcji można skonfigurować przy użyciu polecenia JsonResult. Przykład:

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

Określanie formatu

Aby ograniczyć formaty odpowiedzi, zastosuj [Produces] filtr. Podobnie jak większość filtrów, [Produces] można zastosować na poziomie akcji, kontrolera lub w skali globalnej.

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

Powyższy [Produces] filtr:

  • Wymusza wszystkie akcje w kontrolerze na zwracanie odpowiedzi w formacie JSON dla obiektów POCO (Plain Old CLR Objects) lub ObjectResult i ich typów pochodnych.
  • Jeśli inne formatery są skonfigurowane, a klient określa inny format, zwracany jest format JSON.

Aby uzyskać więcej informacji, zobacz Filtry.

Specjalne formatery wielkości liter

Niektóre specjalne przypadki są implementowane przy użyciu wbudowanych formatatorów. Domyślnie string typy zwracane są formatowane jako tekst/plain (tekst/html, jeśli jest to wymagane za pośrednictwem nagłówka Accept). To zachowanie można usunąć, usuwając element StringOutputFormatter. Formatery danych są usuwane w metodzie ConfigureServices. Akcje, które mają typ zwracanego obiektu modelu, zwracają 204 No Content gdy zwracają null. To zachowanie można usunąć, usuwając element HttpNoContentOutputFormatter. Poniższy kod usuwa elementy StringOutputFormatter i HttpNoContentOutputFormatter.

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

StringOutputFormatterBez wbudowanego formatu string formatującego JSON zwraca typy. Jeśli wbudowany formater JSON zostanie usunięty, a formater XML jest dostępny, formater XML formatuje typy zwracane jako string. string W przeciwnym razie zwracane typy zwracają wartość 406 Not Acceptable.

Bez HttpNoContentOutputFormatter obiekty null są formatowane przy użyciu skonfigurowanego formatera. Przykład:

  • Formater JSON zwraca odpowiedź z treścią null.
  • Funkcja formatowania XML zwraca pusty element XML z zestawem atrybutów xsi:nil="true" .

Mapowanie adresów URL dla formatu odpowiedzi

Klienci mogą zażądać określonego formatu jako części adresu URL, na przykład:

  • W ciągu zapytania lub w części ścieżki.
  • Za pomocą rozszerzenia pliku specyficznego dla formatu, takiego jak .xml lub .json.

Mapowanie ścieżki żądania należy określić w trasie, z której korzysta interfejs API. Przykład:

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

Poprzednia trasa umożliwia określenie żądanego formatu jako opcjonalnego rozszerzenia pliku. Atrybut [FormatFilter] sprawdza, czy wartość formatu istnieje w RouteData i mapuje format odpowiedzi na odpowiedni formatator, gdy odpowiedź jest tworzona.

Route Formatter
/api/products/5 Domyślny formater danych wyjściowych
/api/products/5.json Formater JSON (jeśli został skonfigurowany)
/api/products/5.xml Formater XML (jeśli został skonfigurowany)

ASP.NET Core MVC obsługuje formatowanie danych odpowiedzi przy użyciu określonych formatów lub w odpowiedzi na żądanie klienta.

Wyniki akcji specyficzne dla formatu

Niektóre typy wyników akcji są specyficzne dla określonego formatu, takiego jak JsonResult i ContentResult. Akcje mogą zwracać wyniki, które zawsze używają określonego formatu, ignorując żądanie klienta dla innego formatu. Na przykład zwrócenie JsonResult zwraca dane sformatowane w formacie JSON, a zwrócenie ContentResult zwraca dane ciągów sformatowane w formacie zwykłego tekstu.

Nie jest wymagane, aby akcja zwracała konkretny typ. ASP.NET Core obsługuje dowolną wartość zwracaną przez obiekt. Wyniki akcji, które zwracają obiekty niebędące typami IActionResult, są serializowane przy użyciu odpowiedniej implementacji IOutputFormatter. Aby uzyskać więcej informacji, zobacz Typy zwracane przez akcje kontrolera w ASP.NET Core Web API.

Domyślnie wbudowana metoda ControllerBase.Ok pomocnika zwraca dane w formacie JSON:

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

Przykładowy kod zwraca listę zadań do wykonania. Za pomocą narzędzi deweloperskich przeglądarki F12 lub http-repl z poprzednim kodem wyświetla się:

  • Nagłówek odpowiedzi zawierający typ zawartości:application/json; charset=utf-8.
  • Nagłówki żądania. Na przykład nagłówka Accept. Nagłówek Accept jest ignorowany przez poprzedni kod.

Aby zwrócić dane sformatowane w postaci zwykłego tekstu, użyj ContentResult oraz funkcji pomocniczej Content.

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

W poprzednim kodzie zwracana wartość Content-Type to text/plain.

W przypadku akcji z wieloma typami zwracanymi zwróć wartość IActionResult. Na przykład podczas zwracania różnych kodów stanu HTTP na podstawie wyniku operacji.

Negocjowanie zawartości

Negocjowanie zawartości występuje, gdy klient określa nagłówek "Accept". Domyślny format używany przez ASP.NET Core to JSON. Negocjowanie zawartości jest:

  • Zaimplementowane przez program ObjectResult.
  • Wbudowane wyniki akcji specyficznej dla kodu stanu zwrócone z metod pomocnika. Metody pomocnika wyników akcji są oparte na ObjectResult.

Gdy zwracany jest typ modelu, zwracany typ to ObjectResult.

Poniższa metoda akcji używa metod pomocniczych Ok i NotFound.

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

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

    return Ok(todo);
}

Domyślnie ASP.NET Core obsługuje następujące typy multimediów:

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

Narzędzia, takie jak Fiddler lub http-repl , mogą ustawić Accept nagłówek żądania, aby określić format zwracany. Accept Gdy nagłówek zawiera typ, który obsługuje serwer, zwracany jest ten typ. W następnej sekcji pokazano, jak dodać dodatkowe formatery.

Akcje kontrolera mogą zwracać obiekty POCO (zwykłe, proste obiekty CLR). Gdy zwracany jest POCO, środowisko uruchomieniowe automatycznie tworzy ObjectResult, które opakowuje obiekt. Klient pobiera sformatowany obiekt serializowany. Jeśli zwracany obiekt to null, odpowiedź 204 No Content jest zwracana.

Poniższy przykład zwraca typ obiektu:

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

W poprzednim kodzie żądanie ważnego elementu Todo zwraca odpowiedź 200 OK. Żądanie nieprawidłowego elementu todo zwraca 204 No Content odpowiedź.

Nagłówek Accept

Negocjacja zawartości odbywa się, gdy w żądaniu pojawia się nagłówek Accept. Gdy żądanie zawiera nagłówek 'Accept', ASP.NET Core:

  • Wylicza typy mediów w nagłówku 'Accept' w kolejności preferencji.
  • Próbuje znaleźć formater, który może wygenerować odpowiedź w jednym z określonych formatów.

Jeśli nie znaleziono programu formatującego, który może spełnić żądanie klienta, ASP.NET Core:

  • Zwraca 406 Not Acceptable, jeśli MvcOptions.ReturnHttpNotAcceptable ustawiono na true, lub —
  • Próbuje znaleźć pierwszy formater, który może wygenerować odpowiedź.

Jeśli dla żądanego formatu nie skonfigurowano żadnego formatowania, zostanie użyty pierwszy formater, który może sformatować obiekt. Jeśli w żądaniu nie pojawi się żaden nagłówek Accept.

  • Pierwszy formater, który może obsłużyć obiekt, jest używany do serializacji odpowiedzi.
  • Nie ma żadnych negocjacji. Serwer określa, jaki format ma być zwracany.

pl-PL: Jeśli nagłówek Accept zawiera */*, jest ignorowany, chyba że RespectBrowserAcceptHeader jest ustawione na true dla MvcOptions.

Przeglądarki i negocjacje zawartości

W przeciwieństwie do typowych klientów API, przeglądarki internetowe przekazują Accept nagłówki. Przeglądarki sieci Web określają wiele formatów, w tym symbole wieloznaczne. Domyślnie gdy platforma wykryje, że żądanie pochodzi z przeglądarki:

  • Nagłówek Accept jest ignorowany.
  • Zawartość jest zwracana przy użyciu pierwszego zarejestrowanego formatera danych wyjściowych, który może obsługiwać typ odpowiedzi, chyba że skonfigurowano inaczej.

Takie podejście zapewnia bardziej spójne doświadczenie w przeglądarkach podczas korzystania z API.

Aby skonfigurować aplikację w celu respektowania nagłówków akceptowanych przez przeglądarkę, ustaw RespectBrowserAcceptHeader właściwość na true:

var builder = WebApplication.CreateBuilder(args);

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

Konfigurowanie formaterów

Aplikacje, które muszą obsługiwać dodatkowe formaty, mogą dodawać odpowiednie pakiety NuGet i konfigurować obsługę. Istnieją oddzielne formatery dla danych wejściowych i wyjściowych. Formatery danych wejściowych są używane przez Model Binding. Formatery danych wyjściowych służą do formatowania odpowiedzi. Aby uzyskać informacje na temat tworzenia niestandardowego modułu formatującego, zobacz Niestandardowe formatery.

Wsparcie dla formatu XML

Aby skonfigurować formatery XML zaimplementowane przy użyciu metody XmlSerializer, wywołaj metodę AddXmlSerializerFormatters:

var builder = WebApplication.CreateBuilder(args);

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

W przypadku używania poprzedniego kodu metody kontrolera zwracają odpowiedni format na podstawie nagłówka Accept żądania.

Konfigurowanie formaterów bazujących na System.Text.Json

Aby skonfigurować funkcje dla formaterów opartych na System.Text.Json, użyj Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. Poniższy wyróżniony kod konfiguruje formatowanie PascalCase zamiast domyślnego formatowania camelCase:

var builder = WebApplication.CreateBuilder(args);

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

Aby skonfigurować opcje serializacji danych wyjściowych dla określonych akcji, użyj polecenia JsonResult. Przykład:

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

Dodaj obsługę formatu JSON opartego na Newtonsoft.Json.

Domyślne formatery JSON używają elementu System.Text.Json. Aby użyć formaterów opartych na Newtonsoft.Json, zainstaluj pakiet NuGet Microsoft.AspNetCore.Mvc.NewtonsoftJson i skonfiguruj go w Program.cs.

var builder = WebApplication.CreateBuilder(args);

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

W poprzednim kodzie wywołanie AddNewtonsoftJson konfiguruje następujące funkcje Web API, MVC i Razor Pages do użycia Newtonsoft.Json:

Niektóre funkcje mogą nie działać dobrze z formaterami System.Text.Json i wymagają odwołania do formaterów Newtonsoft.Json. Kontynuuj korzystanie z formaterów opartych na Newtonsoft.Json, gdy aplikacja:

  • Używa Newtonsoft.Json atrybutów. Na przykład: [JsonProperty] lub [JsonIgnore].
  • Dostosowuje ustawienia serializacji.
  • Opiera się na funkcjach, które Newtonsoft.Json udostępnia.

Aby skonfigurować funkcje dla formaterów opartych na Newtonsoft.Json, użyj SerializerSettings:

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

Aby skonfigurować opcje serializacji danych wyjściowych dla określonych akcji, użyj polecenia JsonResult. Przykład:

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

Sformatuj ProblemDetails i ValidationProblemDetails odpowiedzi

Następująca akcja wywołuje ControllerBase.Problem w celu utworzenia odpowiedzi ProblemDetails:

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

ProblemDetails Odpowiedź jest zawsze camelCase, nawet jeśli aplikacja ustawia format na PascalCase. ProblemDetails program jest zgodny z specyfikacją RFC 7807, która określa małe litery.

Po zastosowaniu atrybutu [ApiController] do klasy kontrolera kontroler tworzy odpowiedź ValidationProblemDetails, gdy Walidacja Modelu zakończy się niepowodzeniem. Ta odpowiedź zawiera słownik, który bez zmian używa nazw właściwości modelu jako kluczy błędów. Na przykład poniższy model zawiera jedną właściwość, która wymaga weryfikacji:

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

Domyślnie odpowiedź zwracana, gdy właściwość Value jest nieprawidłowa, używa klucza błędu Value, jak pokazano w poniższym przykładzie:

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

Aby sformatować nazwy właściwości używane jako klucze błędów, dodaj implementację IMetadataDetailsProviderMvcOptions.ModelMetadataDetailsProviders do kolekcji. W poniższym przykładzie dodano implementację opartą na metodzie System.Text.Json, SystemTextJsonValidationMetadataProviderktóra domyślnie formatuje nazwy właściwości jako camelCase:

builder.Services.AddControllers();

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

SystemTextJsonValidationMetadataProvider w swoim konstruktorze akceptuje także implementację JsonNamingPolicy, która określa niestandardowe zasady nazewnictwa do formatowania nazw właściwości.

Aby ustawić niestandardową nazwę właściwości w modelu, użyj atrybutu [JsonPropertyName] we właściwości :

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

ValidationProblemDetails Odpowiedź zwrócona dla poprzedniego modelu, gdy Value właściwość jest nieprawidłowa, używa klucza błędu sampleValue, jak pokazano w poniższym przykładzie:

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

Aby sformatować ValidationProblemDetails odpowiedź przy użyciu polecenia Newtonsoft.Json, użyj polecenia NewtonsoftJsonValidationMetadataProvider:

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

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

Domyślnie NewtonsoftJsonValidationMetadataProvider formatuje nazwy właściwości jako camelCase. NewtonsoftJsonValidationMetadataProvider akceptuje również implementację NamingPolicy w jego konstruktorze, co pozwala określić własne zasady nazewnictwa dla formatowania nazw właściwości. Aby ustawić niestandardową nazwę właściwości w modelu, użyj atrybutu [JsonProperty] .

Określanie formatu

Aby ograniczyć formaty odpowiedzi, zastosuj [Produces] filtr. Podobnie jak większość filtrów, [Produces] można zastosować na poziomie akcji, kontrolera lub poziomu globalnego.

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

Powyższy [Produces] filtr:

  • Wymusza, aby wszystkie akcje w kontrolerze zwracały odpowiedzi sformatowane w formacie JSON dla obiektów typu POCO (zwyczajnych obiektów CLR) lub ObjectResult i jego typów pochodnych.
  • Zwracanie odpowiedzi sformatowanych w formacie JSON, nawet jeśli inne formatatory są skonfigurowane, a klient określa inny format.

Aby uzyskać więcej informacji, zobacz Filtry.

Specjalne formatery do wyjątkowych przypadków

Niektóre specjalne przypadki są implementowane przy użyciu wbudowanych formaterów. Domyślnie string typy zwracane są formatowane jako tekst/zwykły (tekst/html , jeśli jest to wymagane za pośrednictwem nagłówka Accept ). To zachowanie można usunąć, usuwając element StringOutputFormatter. Formatery są usuwane w pliku Program.cs. Akcje, które mają typ zwracanego obiektu modelu, zwracają 204 No Content, kiedy zwracana jest null. To zachowanie można usunąć, usuwając element HttpNoContentOutputFormatter. Poniższy kod usuwa elementy StringOutputFormatter i HttpNoContentOutputFormatter.

var builder = WebApplication.CreateBuilder(args);

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

StringOutputFormatterBez wbudowanego formatu string formatującego JSON zwraca typy. Jeśli wbudowany formater JSON zostanie usunięty, a formater XML jest dostępny, formater XML formatuje typy zwracane jako string. string W przeciwnym razie zwracane typy zwracają wartość 406 Not Acceptable.

Bez HttpNoContentOutputFormatter obiekty null są formatowane przy użyciu skonfigurowanego formatera. Przykład:

  • Formater JSON zwraca odpowiedź z treścią null.
  • Funkcja formatowania XML zwraca pusty element XML z zestawem atrybutów xsi:nil="true" .

Mapowanie adresów URL dla formatu odpowiedzi

Klienci mogą zażądać określonego formatu jako części adresu URL, na przykład:

  • W ciągu zapytania lub w części ścieżki.
  • Za pomocą rozszerzenia pliku specyficznego dla formatu, takiego jak .xml lub .json.

Mapowanie ścieżki żądania należy określić w trasie, z której korzysta interfejs API. Przykład:

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

Poprzednia trasa umożliwia określenie żądanego formatu przy użyciu opcjonalnego rozszerzenia pliku. Atrybut [FormatFilter] sprawdza, czy wartość formatu istnieje w RouteData i mapuje format odpowiedzi na odpowiedni formatator, gdy odpowiedź jest tworzona.

Route Formatter
/api/todoitems/5 Domyślny formater danych wyjściowych
/api/todoitems/5.json Formater JSON (jeśli został skonfigurowany)
/api/todoitems/5.xml Formater XML (jeśli został skonfigurowany)

Deserializacja polimorficzna

Wbudowane funkcje zapewniają ograniczony zakres serializacji polimorficznej, ale w ogóle nie obsługują deserializacji. Deserializacja wymaga niestandardowego konwertera. Zobacz deserializacja polimorficzna, aby uzyskać pełną próbkę deserializacji polimorficznej.

Dodatkowe zasoby