在 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. 傳回不是類型之物件的動作結果 IActionResult 會使用適當的實作為序列化 IOutputFormatterResults 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]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-8The 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.

若要傳回純文字格式化資料,請使用 ContentResultContent 協助程式: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/plainIn the preceding code, the Content-Type returned is text/plain. 傳回字串傳遞 Content-Type text/plainReturning 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:

  • 由實作為 ObjectResultImplemented by ObjectResult.
  • 內建于從 helper 方法傳回的狀態碼特定動作結果。Built into the status code-specific action results returned from the helper methods. 動作結果 helper 方法是以為基礎 ObjectResultThe 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/jsontext/plain 媒體類型。By default, ASP.NET Core supports application/json, text/json, and text/plain media types. FiddlerPostman等工具可以設定 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.

控制器動作可以) (簡單的 CLR 物件傳回 Poco。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.

Accept 標頭The 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:

如果未針對要求的格式設定格式器,則會使用可以格式化物件的第一個格式器。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,否則會忽略標頭 MvcOptionsIf 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 瀏覽器指定許多格式,包括萬用字元。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.

若要將應用程式設定為接受瀏覽器接受標頭,請將設定 RespectBrowserAcceptHeadertrueTo 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

使用執行的 XML 格式器 XmlSerializer 會藉由呼叫下列方式進行設定 AddXmlSerializerFormattersXML formatters implemented using XmlSerializer are configured by calling AddXmlSerializerFormatters:

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

上述程式碼會使用序列化結果 XmlSerializerThe preceding code serializes results using XmlSerializer.

使用上述程式碼時,控制器方法會根據要求的標頭傳回適當的格式 AcceptWhen using the preceding code, controller methods return the appropriate format based on the request's Accept header.

設定 System.Text.Json 基礎格式器Configure System.Text.Json based formatters

System.Text.Json 可以使用設定基礎格式器的功能 Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptionsFeatures for the System.Text.Json based formatters can be configured using Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions. 預設格式為 camelCase。The default formatting is camelCase. 下列反白顯示的程式碼會設定 PascalCase 格式:The following highlighted code sets PascalCase formatting:

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

下列動作方法會呼叫 ControllerBase 來建立 ProblemDetails 回應:The following action method calls ControllerBase.Problem to create a ProblemDetails response:

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

使用上述程式碼:With the preceding code:

  • https://localhost:5001/WeatherForecast/temperature 傳回 PascalCase。https://localhost:5001/WeatherForecast/temperature returns PascalCase.
  • https://localhost:5001/WeatherForecast/error 傳回 camelCase。https://localhost:5001/WeatherForecast/error returns camelCase. 錯誤回應一律是 camelCase,即使應用程式將格式設定為 PascalCase。The error response is always camelCase, even when the app sets the format to PascalCase. ProblemDetails 遵循 RFC 7807,指定小寫ProblemDetails follows RFC 7807, which specifies lower case

下列程式碼會設定 PascalCase 並加入自訂轉換器:The following code sets PascalCase and adds a custom converter:

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

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

您可以使用來設定每個動作的輸出序列化選項 JsonResultOutput serialization options, on a per-action basis, can be configured using JsonResult. 例如:For example:

public IActionResult Get()
{
    return Json(model, new JsonSerializerOptions
    {
        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. Newtonsoft.Json 可以安裝 Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 套件並在中進行設定,以支援根據格式的格式器和功能 Startup.ConfigureServicesSupport 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();
}

在上述程式碼中,呼叫來設定 AddNewtonsoftJson 下列 WEB API、MVC 和 Razor 頁面功能以供使用 Newtonsoft.JsonIn the preceding code, the call to AddNewtonsoftJson configures the following Web API, MVC, and Razor Pages features to use Newtonsoft.Json:

某些功能可能無法搭配使用格式的格式器使用 System.Text.Json ,且需要參考參考格式的格式器 Newtonsoft.JsonSome 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.JsonRelies 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.

Newtonsoft.Json 可以使用下列內容來設定格式的格式器功能 Microsoft.AspNetCore.Mvc.MvcNewtonsoftJsonOptions.SerializerSettingsFeatures 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());
});

您可以使用來設定每個動作的輸出序列化選項 JsonResultOutput 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,
    });
}

新增 XML 格式支援Add XML format support

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

使用執行的 XML 格式器 XmlSerializer 會藉由呼叫下列方式進行設定 AddXmlSerializerFormattersXML formatters implemented using XmlSerializer are configured by calling AddXmlSerializerFormatters:

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

上述程式碼會使用序列化結果 XmlSerializerThe preceding code serializes results using XmlSerializer.

使用上述程式碼時,控制器方法應該根據要求的標頭傳回適當的格式 AcceptWhen 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/純 (text/html AcceptBy default, string return types are formatted as text/plain (text/html if requested via the Accept header). 您可以藉由移除來刪除此行為 StringOutputFormatterThis behavior can be deleted by removing the StringOutputFormatter. 方法中會移除格式器 ConfigureServicesFormatters are removed in the ConfigureServices method. 傳回時,具有模型物件傳回型別的動作 204 No Content nullActions that have a model object return type return 204 No Content when returning null. 您可以藉由移除來刪除此行為 HttpNoContentOutputFormatterThis 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 格式器會傳回包含主體的回應 nullThe 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 格式器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)