在 ASP.NET Core Web API 中格式化回應資料

ASP.NET Core MVC 支援格式化回應資料,使用指定的格式或回應用戶端的要求。

格式特定動作結果

某些動作結果類型是特定格式所特有的,例如 JsonResultContentResult。 動作可以傳回一律使用指定格式的結果,忽略不同格式的用戶端要求。 例如,傳 JsonResult 回會傳 JS 回 ON 格式的資料,並傳回 ContentResult 純文字格式字串資料。

傳回任何特定類型不需要動作。 ASP.NET Core 支援任何物件傳回值。 傳回非 IActionResult 型別物件的動作結果,會使用適當的 IOutputFormatter 實作來序列化。 如需詳細資訊,請參閱 ASP.NET Core Web API 中的控制器動作傳回類型

根據預設,內建協助程式方法 ControllerBase.Ok 會傳回 JS ON 格式的資料:

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

範例程式碼會傳回待辦事項清單。 使用 F12 瀏覽器開發人員工具或 Postman 搭配先前的程式碼會顯示:

  • 包含content-type:application/json; charset=utf-8 的回應標頭。
  • 要求標頭。 例如,標頭 Accept 。 上述程式 Accept 代碼會忽略 標頭。

若要傳回純文字格式化資料,請使用 ContentResultContent 協助程式:

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

在上述程式碼中,傳回的 Content-Typetext/plain

針對具有多個傳回類型的動作,傳回 IActionResult 。 例如,根據作業的結果傳回不同的 HTTP 狀態碼時。

內容交涉

當用戶端指定 Accept 標頭時,就會發生內容交涉。 ASP.NET Core 所使用的預設格式為JS ON。 內容交涉為:

  • 由 實作 ObjectResult
  • 內建于從協助程式方法傳回的狀態碼特定動作結果中。 動作結果協助程式方法是以 為基礎 ObjectResult

傳回模型類型時,傳回類型為 ObjectResult

下列動作方法使用 OkNotFound 協助程式方法:

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

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

    return Ok(todo);
}

根據預設,ASP.NET Core 支援下列媒體類型:

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

FiddlerPostman之類的工具可以設定 Accept 要求標頭來指定傳回格式。 Accept當標頭包含伺服器支援的型別時,會傳回該類型。 下一節說明如何新增其他格式子。

控制器動作可以傳回 POCO (純舊 CLR 物件) 。 傳回 POCO 時,執行時間會自動建立 ObjectResult 包裝 物件的 。 用戶端會取得格式化的序列化物件。 如果傳回的物件是 null204 No Content 則會傳迴響應。

下列範例會傳回物件類型:

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

在上述程式碼中,有效待辦事項的要求會 200 OK 傳迴響應。 無效待辦事項的要求會 204 No Content 傳迴響應。

Accept 標頭

當標頭出現在要求中時 Accept ,就會進行內容涉。 當要求包含 accept 標頭時,ASP.NET Core:

  • 依喜好設定順序列舉 accept 標頭中的媒體類型。
  • 嘗試尋找格式器,以其中一個指定的格式產生回應。

如果找不到滿足用戶端要求的格式器,ASP.NET Core:

如果未針對要求的格式設定格式器,則會使用可以格式化物件的第一個格式器。 如果要求中沒有出現標頭 Accept

  • 可以處理物件的第一個格式器是用來序列化回應。
  • 沒有任何交涉發生。 伺服器正在判斷要傳回的格式。

如果 Accept 標頭包含 */* ,除非 在 上 MvcOptions 設定為 true,否則 RespectBrowserAcceptHeader 會忽略 Header。

瀏覽器和內容交涉

不同于典型的 API 用戶端,網頁瀏覽器會提供 Accept 標頭。 網頁瀏覽器會指定許多格式,包括萬用字元。 根據預設,當架構偵測到要求來自瀏覽器時:

  • Accept 忽略標頭。
  • 除非另有設定,否則會在 ON 中 JS 傳回內容。

此方法可在取用 API 時,跨瀏覽器提供更一致的體驗。

若要將應用程式設定為遵守瀏覽器接受標頭,請將 RespectBrowserAcceptHeader 屬性設定為 true

var builder = WebApplication.CreateBuilder(args);

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

設定格式器

需要支援額外格式的應用程式可以新增適當的 NuGet 套件並設定支援。 輸入和輸出有個別的格式器。 模型系結會使用輸入格式器。 輸出格式器是用來格式化回應。 如需建立自訂格式器的資訊,請參閱 自訂格式器

新增 XML 格式支援

若要設定使用 XmlSerializer 實作的 XML 格式子,請呼叫 AddXmlSerializerFormatters

var builder = WebApplication.CreateBuilder(args);

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

使用上述程式碼時,控制器方法會根據要求的 Accept 標頭傳回適當的格式。

設定 System.Text.Json 格式器

若要設定 System.Text.Json 型格式子的功能,請使用 Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions 。 下列醒目提示的程式碼會設定 PascalCase 格式設定,而不是預設的 camelCase 格式:

var builder = WebApplication.CreateBuilder(args);

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

下列動作方法會呼叫 ControllerBase.Problem 以建立 ProblemDetails 回應:

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

ProblemDetails回應一律為 camelCase,即使應用程式將格式設定為 PascalCase 也一樣。 ProblemDetails 遵循 RFC 7807,指定小寫。

若要針對特定動作設定輸出序列化選項,請使用 JsonResult 。 例如:

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

新增 Newtonsoft.Json 型 JS ON 格式支援

預設 JS ON 格式子使用 System.Text.Json 。 若要使用 Newtonsoft.Json 型格式器,請安裝 Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 套件,並在 中設定 Program.cs 它:

var builder = WebApplication.CreateBuilder(args);

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

在上述程式碼中,呼叫 會 AddNewtonsoftJson 設定下列 Web API、MVC 和 Razor Pages 功能,以使用 Newtonsoft.Json

某些功能可能無法與型格式器搭配 System.Text.Json 使用,而且需要參考 Newtonsoft.Json 以為基礎的格式器。 Newtonsoft.Json當應用程式時,繼續使用格式器:

  • 使用 Newtonsoft.Json 屬性。 例如,[JsonProperty][JsonIgnore]
  • 自訂序列化設定。
  • 依賴提供的功能 Newtonsoft.Json

若要設定 Newtonsoft.Json 型格式子的功能,請使用 SerializerSettings

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

若要針對特定動作設定輸出序列化選項,請使用 JsonResult 。 例如:

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

指定格式

若要限制回應格式,請套 [Produces] 用篩選。 如同大部分 的篩選[Produces] 可以在動作、控制器或全域範圍套用:

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

上述 [Produces] 篩選準則:

  • 強制控制器內的所有動作傳回 JS POCO (純舊 CLR 物件) 或其 ObjectResult 衍生類型的 ON 格式回應。
  • 即使已設定其他格式器,而且用戶端會指定不同的格式,仍會傳回 JS ON 格式的回應。

如需詳細資訊,請參閱 篩選

特殊大小寫格式器

有些特殊案例是使用內建格式器所實作。 根據預設,如果透過 Accept 標頭) 要求, string 傳回類型會格式化為text/plain (text/html。 移除 即可刪除 StringOutputFormatter 此行為。 格式器會在 中移除 Program.cs 。 傳回 時 null ,具有模型物件傳回型別的動作會傳回 204 No Content 。 移除 即可刪除 HttpNoContentOutputFormatter 此行為。 下列程式碼會移除 StringOutputFormatterHttpNoContentOutputFormatter

var builder = WebApplication.CreateBuilder(args);

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

StringOutputFormatter如果沒有 ,內建 JS 的 ON 格式子格式會傳 string 回類型。 如果移除內 JS 建 ON 格式器,且 XML 格式器可供使用,XML 格式器格式 string 會傳回類型。 否則,傳 string 回型別會傳回 406 Not Acceptable

如果沒有 HttpNoContentOutputFormatter,則會使用已設定的格式器來格式化 Null 物件。 例如:

  • JSON 格式子會傳回具有 主體的 null 回應。
  • XML 格式子會傳回具有 屬性 xsi:nil="true" 集的空白 XML 專案。

回應格式 URL 對應

用戶端可以要求特定格式做為 URL 的一部分,例如:

  • 在查詢字串或路徑的一部分。
  • 使用格式特定的副檔名,例如 .xml 或 .json。

應該在 API 所使用的路由中指定要求路徑的對應。 例如:

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

上述路由允許使用選擇性副檔名來指定要求的格式。 屬性 [FormatFilter] 會檢查 中 RouteData 是否有格式值,並在建立回應時,將回應格式對應至適當的格式器。

路由 格式器
/api/todoitems/5 預設輸出格式器
/api/todoitems/5.json 如果已設定) ,則 JS 為 ON 格式器 (
/api/todoitems/5.xml XML 格式器 (如果已設定)

多型還原序列化

內建功能提供有限的多型序列化範圍,但完全不支援還原序列化。 還原序列化需要自訂轉換器。 如需多 型還原序列化 的完整範例,請參閱多型還原序列化。

其他資源

ASP.NET Core MVC 支援格式化回應資料。 回應資料可以使用特定格式格式化,或回應用戶端要求的格式。

檢視或下載範例程式碼 (如何下載)

格式特定動作結果

某些動作結果類型是特定格式所特有的,例如 JsonResultContentResult。 不論用戶端喜好設定為何,動作都可以傳回以特定格式格式化的結果。 例如,傳 JsonResult 回會傳 JS 回 ON 格式的資料。 傳 ContentResult 回 或字串會傳回純文字格式字串資料。

傳回任何特定類型不需要動作。 ASP.NET Core 支援任何物件傳回值。 傳回非 IActionResult 型別物件的動作結果,會使用適當的 IOutputFormatter 實作來序列化。 如需詳細資訊,請參閱 ASP.NET Core Web API 中的控制器動作傳回類型

內建協助程式方法 Ok 會傳 JS 回 ON 格式的資料:

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

範例下載會傳回作者清單。 使用 F12 瀏覽器開發人員工具或 Postman 搭配先前的程式碼:

  • 會顯示包含內容類型:application/json; charset=utf-8 的回應標頭。
  • 要求標頭隨即顯示。 例如,標頭 Accept 。 上述程式 Accept 代碼會忽略 標頭。

若要傳回純文字格式化資料,請使用 ContentResultContent 協助程式:

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

在上述程式碼中,傳回的 Content-Typetext/plain 。 傳回 的字串傳遞 Content-Typetext/plain

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

針對具有多個傳回類型的動作,傳回 IActionResult 。 例如,根據所執行作業的結果傳回不同的 HTTP 狀態碼。

內容交涉

當用戶端指定 Accept 標頭時,就會發生內容交涉。 ASP.NET Core 所使用的預設格式為JS ON。 內容交涉為:

  • 由 實作 ObjectResult
  • 內建于從協助程式方法傳回的狀態碼特定動作結果中。 動作結果協助程式方法是以 為基礎 ObjectResult

傳回模型類型時,傳回類型為 ObjectResult

下列動作方法使用 OkNotFound 協助程式方法:

// 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/jsontext/jsontext/plain 媒體類型。 FiddlerPostman之類的工具可以設定 Accept 要求標頭來指定傳回格式。 Accept當標頭包含伺服器支援的型別時,會傳回該類型。 下一節說明如何新增其他格式子。

控制器動作可以傳回 POCO (純舊 CLR 物件) 。 傳回 POCO 時,執行時間會自動建立 ObjectResult 包裝 物件的 。 用戶端會取得格式化的序列化物件。 如果傳回的物件是 null204 No Content 則會傳迴響應。

傳回物件類型:

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

在上述程式碼中,有效作者別名的要求會 200 OK 傳回具有作者資料的回應。 無效別名的要求會 204 No Content 傳迴響應。

Accept 標頭

當標頭出現在要求中時 Accept ,就會進行內容涉。 當要求包含 accept 標頭時,ASP.NET Core:

  • 依喜好設定順序列舉 accept 標頭中的媒體類型。
  • 嘗試尋找格式器,以其中一個指定的格式產生回應。

如果找不到滿足用戶端要求的格式器,ASP.NET Core:

如果未針對要求的格式設定格式器,則會使用可以格式化物件的第一個格式器。 如果要求中沒有出現標頭 Accept

  • 可以處理物件的第一個格式器是用來序列化回應。
  • 沒有任何交涉發生。 伺服器正在判斷要傳回的格式。

如果 Accept 標頭包含 */* ,除非 在 上 MvcOptions 設定為 true,否則 RespectBrowserAcceptHeader 會忽略 Header。

瀏覽器和內容交涉

不同于典型的 API 用戶端,網頁瀏覽器會提供 Accept 標頭。 網頁瀏覽器會指定許多格式,包括萬用字元。 根據預設,當架構偵測到要求來自瀏覽器時:

  • Accept 忽略標頭。
  • 除非另有設定,否則會在 ON 中 JS 傳回內容。

此方法可在取用 API 時,跨瀏覽器提供更一致的體驗。

若要將應用程式設定為接受瀏覽器接受標頭,請將 設定 RespectBrowserAcceptHeadertrue

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

設定格式器

需要支援其他格式的應用程式可以新增適當的 NuGet 套件並設定支援。 輸入和輸出有個別的格式器。 模型系結會使用輸入格式器。 輸出格式器是用來格式化回應。 如需建立自訂格式器的資訊,請參閱 自訂格式器

新增 XML 格式支援

使用 XmlSerializer 實作的 XML 格式器是藉由呼叫 AddXmlSerializerFormatters 來設定:

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

上述程式碼會使用 XmlSerializer 序列化結果。

使用上述程式碼時,控制器方法會根據要求的 Accept 標頭傳回適當的格式。

設定 System.Text.Json 格式器

System.Text.Json您可以使用 來設定 Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions 型格式器的功能。 預設格式設定為 camelCase。 下列醒目提示的程式碼會設定 PascalCase 格式設定:

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

下列動作方法會呼叫 ControllerBase.Problem 以建立 ProblemDetails 回應:

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

使用上述程式碼:

  • https://localhost:5001/WeatherForecast/temperature 會傳回 PascalCase。
  • https://localhost:5001/WeatherForecast/error 會傳回 camelCase。 即使應用程式將格式設定為 PascalCase,錯誤回應一律為 camelCase。 ProblemDetails 遵循 RFC 7807,指定小寫

下列程式碼會設定 PascalCase,並新增自訂轉換器:

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 。 例如:

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

新增 Newtonsoft.Json 型 JS ON 格式支援

預設 JS ON 格式子是以 為基礎 System.Text.JsonNewtonsoft.Json安裝 NuGet 套件並在 中 Startup.ConfigureServices 設定,即可支援 Microsoft.AspNetCore.Mvc.NewtonsoftJson 以為基礎的格式器與功能。

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

在上述程式碼中,呼叫 會 AddNewtonsoftJson 設定下列 Web API、MVC 和 Razor Pages 功能,以使用 Newtonsoft.Json

某些功能可能無法與型格式器搭配 System.Text.Json 使用,而且需要參考 Newtonsoft.Json 以為基礎的格式器。 Newtonsoft.Json當應用程式時,繼續使用格式器:

  • 使用 Newtonsoft.Json 屬性。 例如,[JsonProperty][JsonIgnore]
  • 自訂序列化設定。
  • 依賴提供的功能 Newtonsoft.Json

Newtonsoft.Json您可以使用 來設定 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 。 例如:

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

指定格式

若要限制回應格式,請套 [Produces] 用篩選。 如同大部分 的篩選[Produces] 可以在動作、控制器或全域範圍套用:

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

上述 [Produces] 篩選準則:

  • 強制控制器內的所有動作傳回 JS POCO (純舊 CLR 物件) 或其 ObjectResult 衍生類型的 ON 格式回應。
  • 如果已設定其他格式器,且用戶端指定不同的格式, JS 則會傳回 ON。

如需詳細資訊,請參閱 篩選

特殊大小寫格式器

有些特殊案例是使用內建格式器所實作。 根據預設,如果透過 Accept 標頭) 要求, string 傳回類型會格式化為text/plain (text/html。 移除 即可刪除 StringOutputFormatter 此行為。 方法中 ConfigureServices 會移除格式器。 傳回 時 null ,具有模型物件傳回型別的動作會傳回 204 No Content 。 移除 即可刪除 HttpNoContentOutputFormatter 此行為。 下列程式碼會移除 StringOutputFormatterHttpNoContentOutputFormatter

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

StringOutputFormatter如果沒有 ,內建 JS 的 ON 格式子格式會傳 string 回類型。 如果移除內 JS 建 ON 格式器,且 XML 格式器可供使用,XML 格式器格式 string 會傳回類型。 否則,傳 string 回型別會傳回 406 Not Acceptable

如果沒有 HttpNoContentOutputFormatter,則會使用已設定的格式器來格式化 Null 物件。 例如:

  • JSON 格式子會傳回具有 主體的 null 回應。
  • XML 格式子會傳回具有 屬性 xsi:nil="true" 集的空白 XML 專案。

回應格式 URL 對應

用戶端可以要求特定格式做為 URL 的一部分,例如:

  • 在查詢字串或路徑的一部分。
  • 使用格式特定的副檔名,例如 .xml 或 .json。

應該在 API 所使用的路由中指定要求路徑的對應。 例如:

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

上述路由允許將要求的格式指定為選擇性副檔名。 屬性 [FormatFilter] 會檢查 中 RouteData 是否有格式值,並在建立回應時,將回應格式對應至適當的格式器。

路由 格式器
/api/products/5 預設輸出格式器
/api/products/5.json 如果已設定) ,則 JS 為 ON 格式器 (
/api/products/5.xml XML 格式器 (如果已設定)

ASP.NET Core MVC 支援格式化回應資料,使用指定的格式或回應用戶端的要求。

格式特定動作結果

某些動作結果類型是特定格式所特有的,例如 JsonResultContentResult。 動作可以傳回一律使用指定格式的結果,忽略不同格式的用戶端要求。 例如,傳 JsonResult 回會傳 JS 回 ON 格式的資料,並傳回 ContentResult 純文字格式字串資料。

傳回任何特定類型不需要動作。 ASP.NET Core 支援任何物件傳回值。 傳回非 IActionResult 型別物件的動作結果,會使用適當的 IOutputFormatter 實作來序列化。 如需詳細資訊,請參閱 ASP.NET Core Web API 中的控制器動作傳回類型

根據預設,內建協助程式方法 ControllerBase.Ok 會傳回 JS ON 格式的資料:

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

範例程式碼會傳回待辦事項清單。 使用 F12 瀏覽器開發人員工具或 Postman 搭配先前的程式碼會顯示:

  • 包含content-type:application/json; charset=utf-8 的回應標頭。
  • 要求標頭。 例如,標頭 Accept 。 上述程式 Accept 代碼會忽略 標頭。

若要傳回純文字格式化資料,請使用 ContentResultContent 協助程式:

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

在上述程式碼中,傳回的 Content-Typetext/plain

針對具有多個傳回類型的動作,傳回 IActionResult 。 例如,根據作業的結果傳回不同的 HTTP 狀態碼時。

內容交涉

用戶端指定 Accept 標頭時,會發生內容交涉。 ASP.NET Core 所使用的預設格式為JS ON。 內容交涉為:

  • 由 實作 ObjectResult
  • 內建于從協助程式方法傳回的狀態碼特定動作結果中。 動作結果協助程式方法是以 為基礎 ObjectResult

傳回模型類型時,傳回型別為 ObjectResult

下列動作方法使用 OkNotFound 協助程式方法:

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

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

    return Ok(todo);
}

根據預設,ASP.NET Core 支援下列媒體類型:

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

FiddlerPostman之類的工具可以設定 Accept 要求標頭來指定傳回格式。 Accept當標頭包含伺服器支援的型別時,就會傳回該類型。 下一節說明如何新增其他格式子。

控制器動作 (一般舊 CLR 物件) 傳回 POC。 傳回 POCO 時,執行時間會自動建立 ObjectResult 包裝物件的 。 用戶端會取得格式化的序列化物件。 如果傳回的物件為 null204 No Content 則會傳迴響應。

下列範例會傳回物件類型:

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

在上述程式碼中,有效的待辦事項要求會 200 OK 傳迴響應。 無效待辦事項的要求會 204 No Content 傳迴響應。

Accept 標頭

當標頭出現在要求中時 Accept ,就會進行內容交涉。 當要求包含接受標頭時,ASP.NET Core:

  • 以喜好設定順序列舉接受標頭中的媒體類型。
  • 嘗試尋找格式器,該格式器可以產生其中一個指定格式的回應。

如果找不到滿足用戶端要求的格式器,ASP.NET Core:

如果未針對要求的格式設定任何格式子,則會使用可以格式化物件的第一個格式器。 如果要求中未 Accept 顯示任何標頭:

  • 可以處理物件的第一個格式器是用來序列化回應。
  • 沒有任何交涉進行。 伺服器會決定要傳回的格式。

如果 Accept 標頭包含 */* ,除非 RespectBrowserAcceptHeader 在 上 MvcOptions 設定為 true,否則會忽略標頭。

瀏覽器和內容交涉

不同于典型的 API 用戶端,網頁瀏覽器會提供 Accept 標頭。 網頁瀏覽器會指定許多格式,包括萬用字元。 根據預設,當架構偵測到要求來自瀏覽器時:

  • Accept 忽略標頭。
  • 除非另有設定,否則內容會在 ON 中 JS 傳回。

此方法會在取用 API 時,跨瀏覽器提供更一致的體驗。

若要設定應用程式以遵守瀏覽器接受標頭,請將 RespectBrowserAcceptHeader 屬性設定為 true

var builder = WebApplication.CreateBuilder(args);

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

設定格式器

需要支援額外格式的應用程式可以新增適當的 NuGet 套件並設定支援。 輸入和輸出有個別的格式器。 模型系結會使用輸入格式器。 輸出格式器是用來格式化回應。 如需建立自訂格式器的資訊,請參閱 自訂格式器

新增 XML 格式支援

若要設定使用 實作 XmlSerializer 的 XML 格式器,請呼叫 AddXmlSerializerFormatters

var builder = WebApplication.CreateBuilder(args);

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

使用上述程式碼時,控制器方法會根據要求的 Accept 標頭傳回適當的格式。

設定 System.Text.Json 型格式器

若要設定 System.Text.Json 型格式子的功能,請使用 Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions 。 下列醒目提示的程式碼會設定 PascalCase 格式設定,而不是預設的 camelCase 格式設定:

var builder = WebApplication.CreateBuilder(args);

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

若要設定特定動作的輸出序列化選項,請使用 JsonResult 。 例如:

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

新增 Newtonsoft.Json 型 JS ON 格式支援

預設 JS ON 格式子會使用 System.Text.Json 。 若要使用 Newtonsoft.Json 型格式器,請安裝 Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 套件,並在 中 Program.cs 加以設定:

var builder = WebApplication.CreateBuilder(args);

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

在上述程式碼中,呼叫 會 AddNewtonsoftJson 設定要使用的下列 Web API、MVC 和 Razor Pages 功能 Newtonsoft.Json

某些功能可能無法與以格式器為基礎的格式器搭配使用 System.Text.Json ,而且需要參考 Newtonsoft.Json 以為基礎的格式器。 當應用程式時 Newtonsoft.Json ,繼續使用以為基礎的格式器:

  • 使用 Newtonsoft.Json 屬性。 例如,[JsonProperty][JsonIgnore]
  • 自訂序列化設定。
  • 依賴提供的功能 Newtonsoft.Json

若要設定 Newtonsoft.Json 型格式子的功能,請使用 SerializerSettings

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

若要設定特定動作的輸出序列化選項,請使用 JsonResult 。 例如:

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

格式 ProblemDetailsValidationProblemDetails 回應

下列動作方法會呼叫 ControllerBase.Problem 以建立 ProblemDetails 回應:

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

ProblemDetails即使應用程式將格式設定為 PascalCase,回應一律為 camelCase。 ProblemDetails 遵循 RFC 7807,指定小寫。

當屬性 [ApiController] 套用至控制器類別時,控制器會在 ValidationProblemDetails模型驗證 失敗時建立回應。 此回應包含使用模型屬性名稱做為錯誤索引鍵的字典,不會變更。 例如,下列模型包含需要驗證的單一屬性:

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

根據預設, ValidationProblemDetails 當 屬性無效時所傳回的 Value 回應會使用 的錯誤 Value 索引鍵,如下列範例所示:

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

若要格式化做為錯誤索引鍵的屬性名稱,請將 的 IMetadataDetailsProvider 實作新增至 MvcOptions.ModelMetadataDetailsProviders 集合。 下列範例會新增 System.Text.Json 架構實作, SystemTextJsonValidationMetadataProvider 預設會將屬性名稱格式化為 camelCase:

builder.Services.AddControllers();

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

SystemTextJsonValidationMetadataProvider 也會在其建構函式中接受 的 JsonNamingPolicy 實作,以指定格式化屬性名稱的自訂命名原則。

若要設定模型內屬性的自訂名稱,請在 屬性上使用 [JsonPropertyName] 屬性:

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

ValidationProblemDetails 屬性無效時 Value ,為上述模型的回應會使用 的錯誤索引鍵 sampleValue ,如下列範例所示:

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

若要使用 Newtonsoft.Json 格式化 ValidationProblemDetails 回應,請使用 NewtonsoftJsonValidationMetadataProvider

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

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

根據預設, NewtonsoftJsonValidationMetadataProvider 會將屬性名稱格式化為 camelCase。 NewtonsoftJsonValidationMetadataProvider 也會在其建構函式中接受 的 NamingPolicy 實作,以指定格式化屬性名稱的自訂命名原則。 若要設定模型內屬性的自訂名稱,請使用 [JsonProperty] 屬性。

指定格式

若要限制回應格式,請套 [Produces] 用篩選。 如同大部分 的篩選[Produces] 可以在動作、控制器或全域範圍套用:

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

上述 [Produces] 篩選準則:

  • 強制控制器內的所有動作傳回 JS POCos (純舊 CLR 物件) 或其 ObjectResult 衍生類型的 ON 格式回應。
  • 即使已設定其他格式器,而且用戶端會指定不同的格式,仍會傳回 JS ON 格式的回應。

如需詳細資訊,請參閱 篩選

特殊案例格式器

有些特殊案例是使用內建格式器所實作。 根據預設, string 如果透過 Accept 標頭要求,傳回型別會格式化為text/plain (text/html) 。 移除 即可刪除 StringOutputFormatter 此行為。 格式器會在 中移除 Program.cs 。 傳回 時 null ,具有模型物件傳回型別的動作會傳回 204 No Content 。 移除 即可刪除 HttpNoContentOutputFormatter 此行為。 下列程式碼會移除 StringOutputFormatterHttpNoContentOutputFormatter

var builder = WebApplication.CreateBuilder(args);

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

StringOutputFormatter如果沒有 ,內建 JS 的 ON 格式子格式會傳 string 回類型。 如果移除內 JS 建 ON 格式器,且 XML 格式器可供使用,XML 格式器格式 string 會傳回類型。 否則,傳 string 回型別會傳回 406 Not Acceptable

如果沒有 HttpNoContentOutputFormatter,則會使用已設定的格式器來格式化 Null 物件。 例如:

  • JSON 格式子會傳回具有 主體的 null 回應。
  • XML 格式子會傳回具有 屬性 xsi:nil="true" 集的空白 XML 專案。

回應格式 URL 對應

用戶端可以要求特定格式做為 URL 的一部分,例如:

  • 在查詢字串或路徑的一部分。
  • 使用格式特定的副檔名,例如 .xml 或 .json。

應該在 API 所使用的路由中指定要求路徑的對應。 例如:

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

上述路由允許使用選擇性副檔名來指定要求的格式。 屬性 [FormatFilter] 會檢查 中 RouteData 是否有格式值,並在建立回應時,將回應格式對應至適當的格式器。

路由 格式器
/api/todoitems/5 預設輸出格式器
/api/todoitems/5.json 如果已設定) ,則 JS 為 ON 格式器 (
/api/todoitems/5.xml XML 格式器 (如果已設定)

多型還原序列化

內建功能提供有限的多型序列化範圍,但完全不支援還原序列化。 還原序列化需要自訂轉換器。 如需多 型還原序列化 的完整範例,請參閱多型還原序列化。

其他資源