在 ASP.NET Core Web API 中格式化回應資料
ASP.NET Core MVC 支援格式化回應資料,使用指定的格式或回應用戶端的要求。
格式特定動作結果
某些動作結果類型是特定格式所特有的,例如 JsonResult 和 ContentResult。 動作可以傳回一律使用指定格式的結果,忽略不同格式的用戶端要求。 例如,傳 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
代碼會忽略 標頭。
若要傳回純文字格式化資料,請使用 ContentResult 和 Content 協助程式:
[HttpGet("Version")]
public ContentResult GetVersion() =>
Content("v1.0.0");
在上述程式碼中,傳回的 Content-Type
是 text/plain
。
針對具有多個傳回類型的動作,傳回 IActionResult
。 例如,根據作業的結果傳回不同的 HTTP 狀態碼時。
內容交涉
當用戶端指定 Accept 標頭時,就會發生內容交涉。 ASP.NET Core 所使用的預設格式為JS ON。 內容交涉為:
- 由 實作 ObjectResult 。
- 內建于從協助程式方法傳回的狀態碼特定動作結果中。 動作結果協助程式方法是以 為基礎
ObjectResult
。
傳回模型類型時,傳回類型為 ObjectResult
。
下列動作方法使用 Ok
和 NotFound
協助程式方法:
[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
Fiddler或Postman之類的工具可以設定 Accept
要求標頭來指定傳回格式。 Accept
當標頭包含伺服器支援的型別時,會傳回該類型。 下一節說明如何新增其他格式子。
控制器動作可以傳回 POCO (純舊 CLR 物件) 。 傳回 POCO 時,執行時間會自動建立 ObjectResult
包裝 物件的 。 用戶端會取得格式化的序列化物件。 如果傳回的物件是 null
, 204 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:
- 如果 MvcOptions.ReturnHttpNotAcceptable 設定為
true
,則傳406 Not Acceptable
回 , 或 - - 嘗試尋找可以產生回應的第一個格式器。
如果未針對要求的格式設定格式器,則會使用可以格式化物件的第一個格式器。 如果要求中沒有出現標頭 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
:
- 讀取和寫入 JS ON 的輸入和輸出格式器
- JsonResult
- JSON Patch
- IJsonHelper
- TempData
某些功能可能無法與型格式器搭配 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 此行為。 下列程式碼會移除 StringOutputFormatter
和 HttpNoContentOutputFormatter
。
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 支援格式化回應資料。 回應資料可以使用特定格式格式化,或回應用戶端要求的格式。
格式特定動作結果
某些動作結果類型是特定格式所特有的,例如 JsonResult 和 ContentResult。 不論用戶端喜好設定為何,動作都可以傳回以特定格式格式化的結果。 例如,傳 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
代碼會忽略 標頭。
若要傳回純文字格式化資料,請使用 ContentResult 和 Content 協助程式:
// GET api/authors/about
[HttpGet("About")]
public ContentResult About()
{
return Content("An API listing authors of docs.asp.net.");
}
在上述程式碼中,傳回的 Content-Type
是 text/plain
。 傳回 的字串傳遞 Content-Type
text/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
。
下列動作方法使用 Ok
和 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);
}
根據預設,ASP.NET Core 支援 application/json
、 text/json
和 text/plain
媒體類型。 Fiddler或Postman之類的工具可以設定 Accept
要求標頭來指定傳回格式。 Accept
當標頭包含伺服器支援的型別時,會傳回該類型。 下一節說明如何新增其他格式子。
控制器動作可以傳回 POCO (純舊 CLR 物件) 。 傳回 POCO 時,執行時間會自動建立 ObjectResult
包裝 物件的 。 用戶端會取得格式化的序列化物件。 如果傳回的物件是 null
, 204 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:
- 如果 MvcOptions.ReturnHttpNotAcceptable 設定為
true
,則傳406 Not Acceptable
回 , 或 - - 嘗試尋找可以產生回應的第一個格式器。
如果未針對要求的格式設定格式器,則會使用可以格式化物件的第一個格式器。 如果要求中沒有出現標頭 Accept
:
- 可以處理物件的第一個格式器是用來序列化回應。
- 沒有任何交涉發生。 伺服器正在判斷要傳回的格式。
如果 Accept 標頭包含 */*
,除非 在 上 MvcOptions 設定為 true,否則 RespectBrowserAcceptHeader
會忽略 Header。
瀏覽器和內容交涉
不同于典型的 API 用戶端,網頁瀏覽器會提供 Accept
標頭。 網頁瀏覽器會指定許多格式,包括萬用字元。 根據預設,當架構偵測到要求來自瀏覽器時:
- 會
Accept
忽略標頭。 - 除非另有設定,否則會在 ON 中 JS 傳回內容。
此方法可在取用 API 時,跨瀏覽器提供更一致的體驗。
若要將應用程式設定為接受瀏覽器接受標頭,請將 設定 RespectBrowserAcceptHeader 為 true
:
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.Json
。 Newtonsoft.Json
安裝 NuGet 套件並在 中 Startup.ConfigureServices
設定,即可支援 Microsoft.AspNetCore.Mvc.NewtonsoftJson
以為基礎的格式器與功能。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson();
}
在上述程式碼中,呼叫 會 AddNewtonsoftJson
設定下列 Web API、MVC 和 Razor Pages 功能,以使用 Newtonsoft.Json
:
- 讀取和寫入 JS ON 的輸入和輸出格式器
- JsonResult
- JSON Patch
- IJsonHelper
- TempData
某些功能可能無法與型格式器搭配 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 此行為。 下列程式碼會移除 StringOutputFormatter
和 HttpNoContentOutputFormatter
。
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 支援格式化回應資料,使用指定的格式或回應用戶端的要求。
格式特定動作結果
某些動作結果類型是特定格式所特有的,例如 JsonResult 和 ContentResult。 動作可以傳回一律使用指定格式的結果,忽略不同格式的用戶端要求。 例如,傳 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
代碼會忽略 標頭。
若要傳回純文字格式化資料,請使用 ContentResult 和 Content 協助程式:
[HttpGet("Version")]
public ContentResult GetVersion()
=> Content("v1.0.0");
在上述程式碼中,傳回的 Content-Type
是 text/plain
。
針對具有多個傳回類型的動作,傳回 IActionResult
。 例如,根據作業的結果傳回不同的 HTTP 狀態碼時。
內容交涉
用戶端指定 Accept 標頭時,會發生內容交涉。 ASP.NET Core 所使用的預設格式為JS ON。 內容交涉為:
- 由 實作 ObjectResult 。
- 內建于從協助程式方法傳回的狀態碼特定動作結果中。 動作結果協助程式方法是以 為基礎
ObjectResult
。
傳回模型類型時,傳回型別為 ObjectResult
。
下列動作方法使用 Ok
和 NotFound
協助程式方法:
[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
Fiddler或Postman之類的工具可以設定 Accept
要求標頭來指定傳回格式。 Accept
當標頭包含伺服器支援的型別時,就會傳回該類型。 下一節說明如何新增其他格式子。
控制器動作 (一般舊 CLR 物件) 傳回 POC。 傳回 POCO 時,執行時間會自動建立 ObjectResult
包裝物件的 。 用戶端會取得格式化的序列化物件。 如果傳回的物件為 null
, 204 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:
406 Not Acceptable
如果 MvcOptions.ReturnHttpNotAcceptable 設定為true
,則傳回 , 或 -- 嘗試尋找可產生回應的第一個格式器。
如果未針對要求的格式設定任何格式子,則會使用可以格式化物件的第一個格式器。 如果要求中未 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
:
- 讀取和寫入 JS ON 的輸入和輸出格式器
- JsonResult
- JSON Patch
- IJsonHelper
- TempData
某些功能可能無法與以格式器為基礎的格式器搭配使用 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() });
格式 ProblemDetails
和 ValidationProblemDetails
回應
下列動作方法會呼叫 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 此行為。 下列程式碼會移除 StringOutputFormatter
和 HttpNoContentOutputFormatter
。
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 格式器 (如果已設定) |
多型還原序列化
內建功能提供有限的多型序列化範圍,但完全不支援還原序列化。 還原序列化需要自訂轉換器。 如需多 型還原序列化 的完整範例,請參閱多型還原序列化。