在 ASP.NET Core Web API 中格式化回應資料Format response data in ASP.NET Core Web API

Rick AndersonSteve Smith 撰寫By Rick Anderson and Steve Smith

ASP.NET Core MVC 支援格式化回應資料。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

某些動作結果類型是特定格式所特有的,例如 JsonResultContentResultSome 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. 傳回不是 @no__t 0 類型物件之動作的結果,會使用適當的 IOutputFormatter 執行進行序列化。Results from actions that return objects that are not IActionResult types are serialized using the appropriate IOutputFormatter implementation. 如需詳細資訊,請參閱ASP.NET Core Web API 中的控制器動作傳回類型For more information, see ASP.NET Core Web API 中的控制器動作傳回類型.

內建 helper 方法 Ok 會傳回 JSON 格式的資料: [!code-csharp @ no__t-2The 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:

  • 顯示包含內容類型: 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.

若要傳回純文字格式化資料,請使用 ContentContent 協助程式:To return plain text formatted data, use Content and the Content helper:

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

在上述程式碼中,傳回的 Content-Typetext/plainIn the preceding code, the Content-Type returned is text/plain. 傳回字串會傳遞 text/plainContent-TypeReturning a string delivers Content-Type of text/plain:

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

針對具有多個傳回類型的動作,傳回 IActionResultFor 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 使用的預設格式為JSONThe default format used by ASP.NET Core is JSON. 內容協商為:Content negotiation is:

  • ObjectResult 來執行。Implemented by ObjectResult.
  • 內建自 helper 方法所傳回的狀態碼特定動作結果。Built into the status code-specific action results returned from the helper methods. 動作結果 helper 方法是以 ObjectResult 為基礎。The action results helper methods are based on ObjectResult.

傳回模型型別時,傳回型別會 ObjectResultWhen a model type is returned, the return type is ObjectResult.

下列動作方法使用 OkNotFound 協助程式方法: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/jsontext/json 和 @no__t 2 媒體類型。By default, ASP.NET Core supports application/json, text/json, and text/plain media types. FiddlerPostman這類工具可以設定 @no__t 2 要求標頭,以指定傳回格式。Tools such as Fiddler or Postman can set the Accept request header to specify the return format. 當 @no__t 0 標頭包含伺服器支援的類型時,就會傳回該類型。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 傳回時,執行時間會自動建立包裝物件的 ObjectResultWhen 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);
}

在上述程式碼中,有效作者別名的要求會傳回具有作者資料的 @no__t 0 回應。In the preceding code, a request for a valid author alias returns a 200 OK response with the author's data. 對無效別名的要求會傳回 @no__t 0 回應。A request for an invalid alias returns a 204 No Content response.

Accept 標頭The Accept header

當要求中出現 @no__t 1 標頭時,就會進行內容協商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:

  • 如果已設定 MvcOptions,則傳回 406 Not Acceptable,或-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 標頭包含 */*,除非 RespectBrowserAcceptHeaderMvcOptions 上設定為 true,否則會忽略標頭。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 設為 trueTo 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. 如需建立自訂格式器的詳細資訊,請參閱自訂格式化器。For information on creating a custom formatter, see Custom Formatters.

新增 XML 格式支援Add XML format support

使用 XmlSerializer 來執行的 XML 格式器是藉由呼叫 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 should return the appropriate format based on the request's Accept header.

設定 System.Text.Json-based 格式器Configure 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.SerializerOptions.PropertyNamingPolicy = null;

    // Configure a custom converter.
    options.SerializerOptions.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
    {
        options.WriteIndented = true,
    });
}

新增 Newtonsoft.Json 型 JSON 格式支援Add 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. 藉由安裝NewtonsoftJson NuGet 套件並在 Startup.ConfigureServices 中進行設定,可取得 @no__t 0 型格式器和功能的支援。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();
}

某些功能可能不適用於 @no__t 4.9.0-格式的格式器,而且需要參考 Newtonsoft.Json 格式的格式化程式。Some features may not work well with System.Text.Json-based formatters and require a reference to the Newtonsoft.Json-based formatters. 如果應用程式有下列情況,請繼續使用以 @no__t 4.9.0-為基礎的格式器: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.SerializerSettingsConfigures Microsoft.AspNetCore.Mvc.JsonResult.SerializerSettings. 在 ASP.NET Core 3.0 版之前,JsonResult.SerializerSettings 接受 Newtonsoft.Json 專屬的 JsonSerializerSettings 執行個體。Prior to ASP.NET Core 3.0, JsonResult.SerializerSettings accepts an instance of JsonSerializerSettings that is specific to Newtonsoft.Json.
  • 產生 OpenAPI 文件。Generates OpenAPI documentation.

@No__t 4.9.0-型格式器的功能可以使用 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.SerializerOptions.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
    {
        options.Formatting = Formatting.Indented,
    });
}

新增 XML 格式支援Add XML format support

XML 格式設定需要AspNetCore 的 xml NuGet 套件。XML formatting requires the Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet package.

使用 XmlSerializer 來執行的 XML 格式器是藉由呼叫 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.

如需詳細資訊,請參閱篩選For more information, see Filters.

特殊案例格式器Special case formatters

有些特殊案例是使用內建格式器所實作。Some special cases are implemented using built-in formatters. 根據預設,string 傳回類型會格式化為text/純文字(如果透過 Accept 標頭要求,則為text/html )。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. 傳回 null 時,具有模型物件傳回類型的動作會傳回 204 No ContentActions that have a model object return type return 204 No Content when returning null. 您可以藉由移除 HttpNoContentOutputFormatter 來刪除此行為。This behavior can be deleted by removing the HttpNoContentOutputFormatter. 下列程式碼會移除 StringOutputFormatterHttpNoContentOutputFormatterThe 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 格式器,則 XML 格式器格式 string 傳回類型。If the built-in JSON formatter is removed and an XML formatter is available, the XML formatter formats string return types. 否則,string 傳回類型會傳回 406 Not AcceptableOtherwise, 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. @No__t 1屬性會檢查 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 格式器Formatter
/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)