ASP.NET Core Web API の応答データの書式設定
ASP.NET Core MVC では、指定した形式を使用するか、クライアントの要求に応答して、応答データの書式設定をサポートしています。
書式固有アクションの結果
アクションの結果には、JsonResult や ContentResult のように、特定の形式に固有となる型があります。 アクションは、常に指定された形式を使用する結果を返すことができます。別の形式に対するクライアントの要求は無視されます。 たとえば、 を返JSすJsonResult
場合は ON 形式のデータが返され、 をContentResult
返す場合はプレーンテキスト形式の文字列データが返されます。
アクションが特定の型を返す必要はありません。 ASP.NET Core によって、すべてのオブジェクトの戻り値がサポートされます。 型ではない IActionResult オブジェクトを返すアクションの結果は、適切な IOutputFormatter 実装を使用してシリアル化されます。 詳細については、「ASP.NET Core Web API のコントローラー アクションの戻り値の型」を参照してください。
既定では、組み込みのヘルパー メソッド ControllerBase.Ok は ON 形式のデータを JS返します。
[HttpGet]
public IActionResult Get() =>
Ok(_todoItemStore.GetList());
サンプル コードは、todo 項目の一覧を返します。 前のコードで 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で使用される既定の形式は ON ですJS。 コンテンツ ネゴシエーションの説明を以下に示します。
- 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);
前のコードでは、有効な todo アイテムの要求から応答が 200 OK
返されます。 無効な todo アイテムに対する要求は、応答を 204 No Content
返します。
Accept ヘッダー
コンテンツ "ネゴシエーション" は、Accept
ヘッダーが要求に含まれるときに発生します。 要求に Accept ヘッダーが含まれるとき、ASP.NET Core は次のように処理します。
- Accept ヘッダーのメディアの種類を優先順で列挙します。
- 指定された形式のいずれかで応答を生成できるフォーマッタを見つけようとします。
クライアントの要求を満たすことができるフォーマッタが見つからない場合は、ASP.NET Core は次のようにします。
- MvcOptions.ReturnHttpNotAcceptable が
true
に設定されている場合は、406 Not Acceptable
を返します。 - 応答を生成できる最初のフォーマッタを見つけようとします。
要求された形式に対応するフォーマッタが構成されていない場合、オブジェクトを書式設定できる最初のフォーマッタが使用されます。 要求に Accept
ヘッダーが表示されない場合は、次のようになります。
- オブジェクトを処理できる最初のフォーマッタが使用されて、応答をシリアル化します。
- ネゴシエーションは発生しません。 サーバーが返す形式を決定します。
Accept ヘッダーに */*
が含まれる場合、RespectBrowserAcceptHeader
が MvcOptions で true に設定されていない限り、ヘッダーが無視されます。
ブラウザーとコンテンツ ネゴシエーション
一般的な API クライアントとは異なり、Web ブラウザーは Accept
ヘッダーを提供します。 Web ブラウザーでは、ワイルドカードを含む多くの形式が指定されています。 既定では、要求がブラウザーから送信されていることをフレームワークが検出すると、次のようになります。
Accept
ヘッダーは無視されます。- 特に構成されていない限り、コンテンツは ON で JS返されます。
この方法では、API を使用する際にブラウザー間でより一貫性のあるエクスペリエンスが提供されます。
ブラウザーでヘッダーを受け入れるようにアプリを構成するには、 プロパティを RespectBrowserAcceptHeader に true
設定します。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
options.RespectBrowserAcceptHeader = true;
});
フォーマッタの構成
追加の形式をサポートする必要があるアプリでは、適切な NuGet パッケージを追加し、サポートを構成できます。 入力と出力で別々のフォーマッタがあります。 入力フォーマッタは、モデル バインドによって使用されます。 出力フォーマッタは、応答の書式設定に使用されます。 カスタム フォーマッタの作成の詳細については、カスタム フォーマッタに関するページを参照してください。
XML 形式のサポートを追加する
を使用して実装された XML フォーマッタを XmlSerializer構成するには、 を呼び出します AddXmlSerializerFormatters。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddXmlSerializerFormatters();
前のコードを使用する場合、コントローラー メソッドは要求の Accept
ヘッダーに基づいて適切な形式を返します。
ベースのフォーマッタを構成 System.Text.Json
する
ベースのフォーマッタの機能を System.Text.Json
構成するには、 を使用 Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptionsします。 次の強調表示されたコードは、既定の camelCase 書式設定ではなく、PascalCase の書式設定を構成します。
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
アプリで形式が PascalCase に設定されている場合でも、応答は常にキャメルケースです。 ProblemDetails
は、小文字を指定する RFC 7807 に従います。
特定のアクションの出力シリアル化オプションを構成するには、 を使用 JsonResult
します。 次に例を示します。
[HttpGet]
public IActionResult Get() =>
new JsonResult(
_todoItemStore.GetList(),
new JsonSerializerOptions
{
PropertyNamingPolicy = null
});
ベースJSの ON 形式のサポートを追加Newtonsoft.Json
する
既定の ON フォーマッタでは、 が使用System.Text.Json
されますJS。 ベースのフォーマッタを Newtonsoft.Json
使用するには、NuGet パッケージを Microsoft.AspNetCore.Mvc.NewtonsoftJson
インストールし、 で Program.cs
構成します。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddNewtonsoftJson();
前のコードでは、AddNewtonsoftJson
を呼び出すことで、次の Web API、MVC、Razor Pages の各機能が、Newtonsoft.Json
を使用するように構成されます。
- ON の読み取りと書き込 JSみを行う入力フォーマッタと出力フォーマッタ
- 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]
フィルターでは以下の処理が行われます。
- コントローラー内のすべてのアクションで、POC (Plain Old CLR Objects) またはそのObjectResult派生型に対する ON 形式の応答を強制的に返JSします。
- 他のフォーマッタが構成されていて、クライアントが別の形式を指定している場合でも、ON 形式の応答を返 JSします。
詳細については、フィルターに関するページを参照してください。
特殊なケースのフォーマッタ
一部の特殊なケースが組み込みのフォーマッタで実装されます。 既定では、戻り値の型 string
は text/plain として書式設定されます (Accept
ヘッダー経由で要求された場合は 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
がない場合、組み込みの ON フォーマッタ形式string
はJS型を返します。 組み込みの JSON フォーマッタが削除され、XML フォーマッタが使用可能な場合、XML フォーマッタ形式 string
は型を返します。 それ以外の場合は、戻り値の型 string
で 406 Not Acceptable
が返されます。
HttpNoContentOutputFormatter
がない場合、構成されているフォーマッタを利用し、null オブジェクトが書式設定されます。 次に例を示します。
- ON フォーマッタは JS、 の本文
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 |
JSON フォーマッタ (構成されている場合) |
/api/todoitems/5.xml |
XML フォーマッタ (構成される場合) |
ポリモーフィックな逆シリアル化
組み込み機能では、ポリモーフィックなシリアル化は限られた範囲で提供されていますが、逆シリアル化はまったくサポートされていません。 逆シリアル化を行うには、カスタム コンバーターが必要です。 ポリモーフィック逆シリアル化の完全なサンプルについては、「ポリモーフィック逆シリアル化」を参照してください。
その他のリソース
- サンプル コードを表示またはダウンロードします (ダウンロード方法)。
ASP.NET Core MVC では、応答データの書式設定がサポートされます。 応答データは、特定の形式を使用して、またはクライアントが要求した形式に応じて書式設定できます。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
書式固有アクションの結果
アクションの結果には、JsonResult や ContentResult のように、特定の形式に固有となる型があります。 アクションでは、クライアントの設定に関係なく、特定の形式で書式設定された結果を返すことができます。 たとえば、 を返す場合 JsonResult
、ON 形式の JSデータが返されます。 ContentResult
または文字列を返すと、プレーンテキスト形式の文字列データが返されます。
アクションが特定の型を返す必要はありません。 ASP.NET Core によって、すべてのオブジェクトの戻り値がサポートされます。 型ではない IActionResult オブジェクトを返すアクションの結果は、適切な IOutputFormatter 実装を使用してシリアル化されます。 詳細については、「ASP.NET Core Web API でのコントローラー アクションの戻り値の型」を参照してください。
組み込みのヘルパー メソッド Ok は、ON 形式のデータを JS返します。
// GET: api/authors
[HttpGet]
public ActionResult Get()
{
return Ok(_authors.List());
}
サンプル ダウンロードでは作成者の一覧が返されます。 F12 ブラウザー開発者ツールまたは Postman と前のコードを使用します。
- content-type:
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
です。 文字列を返すと、text/plain
の Content-Type
が送られます。
// GET api/authors/version
[HttpGet("version")]
public string Version()
{
return "Version 1.0.0";
}
戻り値の型が複数あるアクションの場合は、IActionResult
を返します。 たとえば、実行された操作の結果に基づいて、さまざまな HTTP 状態コードを返します。
コンテンツ ネゴシエーション
クライアントにより Accept ヘッダーが指定されると、コンテンツ ネゴシエーションが発生します。 ASP.NET Coreで使用される既定の形式は ON ですJS。 コンテンツ ネゴシエーションの説明を以下に示します。
- 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 ヘッダーに */*
が含まれる場合、RespectBrowserAcceptHeader
が MvcOptions で true に設定されていない限り、ヘッダーが無視されます。
ブラウザーとコンテンツ ネゴシエーション
一般的な API クライアントとは異なり、Web ブラウザーは Accept
ヘッダーを提供します。 Web ブラウザーでは、ワイルドカードを含む多くの形式が指定されています。 既定では、要求がブラウザーから送信されていることをフレームワークが検出すると、次のようになります。
Accept
ヘッダーは無視されます。- 特に構成されていない限り、コンテンツは ON で JS返されます。
この方法では、API を使用する際にブラウザー間でより一貫性のあるエクスペリエンスが提供されます。
ブラウザーの Accept ヘッダーを優先するようにアプリを構成するには、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 を使用して構成することができます。 既定の書式設定はキャメルケースです。 次の強調されたコードは、パスカルケースで書式が設定されています。
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
からはパスカルケースが返されます。https://localhost:5001/WeatherForecast/error
からはキャメルケースが返されます。 エラー応答は、アプリで書式がパスカルケースに設定されている場合でも、常にキャメルケースになります。ProblemDetails
が従う RFC 7807 では、小文字が指定されています
次のコードでは、パスカルケースが設定されて、カスタム コンバーターが追加されます。
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
ベースのフォーマッタと機能のサポートは、Microsoft.AspNetCore.Mvc.NewtonsoftJson
NuGet パッケージをインストールし、Startup.ConfigureServices
でそれを構成することにより利用できます。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson();
}
前のコードでは、AddNewtonsoftJson
を呼び出すことで、次の Web API、MVC、Razor Pages の各機能が、Newtonsoft.Json
を使用するように構成されます。
- ON の読み取りと書き込 JSみを行う入力フォーマッタと出力フォーマッタ
- 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]
フィルターでは以下の処理が行われます。
- コントローラー内のすべてのアクションに対して、POC (Plain Old CLR Objects) またはそのObjectResult派生型に対する ON 形式の応答を強制的に返JSします。
- 他のフォーマッタが構成されていて、クライアントが別の形式を指定している場合は、 JSON が返されます。
詳細については、フィルターに関するページを参照してください。
特殊なケースのフォーマッタ
一部の特殊なケースが組み込みのフォーマッタで実装されます。 既定では、戻り値の型 string
は text/plain として書式設定されます (Accept
ヘッダー経由で要求された場合は 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
を指定しない場合、組み込みの JSON フォーマッタ形式string
は型を返します。 組み込みの JSON フォーマッタが削除され、XML フォーマッタが使用可能な場合、XML フォーマッタ形式 string
は型を返します。 それ以外の場合は、戻り値の型 string
で 406 Not Acceptable
が返されます。
HttpNoContentOutputFormatter
がない場合、構成されているフォーマッタを利用し、null オブジェクトが書式設定されます。 次に例を示します。
- ON フォーマッタは JS、 の本文
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 |
JSON フォーマッタ (構成されている場合) |
/api/products/5.xml |
XML フォーマッタ (構成される場合) |
ASP.NET Core MVC では、指定した形式を使用するか、クライアントの要求に応答して、応答データの書式設定をサポートしています。
書式固有アクションの結果
アクションの結果には、JsonResult や ContentResult のように、特定の形式に固有となる型があります。 アクションは、常に指定された形式を使用する結果を返すことができます。別の形式に対するクライアントの要求は無視されます。 たとえば、 を返JSすJsonResult
場合は ON 形式のデータが返され、 をContentResult
返す場合はプレーンテキスト形式の文字列データが返されます。
アクションが特定の型を返す必要はありません。 ASP.NET Core によって、すべてのオブジェクトの戻り値がサポートされます。 型ではない IActionResult オブジェクトを返すアクションの結果は、適切な IOutputFormatter 実装を使用してシリアル化されます。 詳細については、「ASP.NET Core Web API のコントローラー アクションの戻り値の型」を参照してください。
既定では、組み込みのヘルパー メソッド ControllerBase.Ok は ON 形式のデータを JS返します。
[HttpGet]
public IActionResult Get()
=> Ok(_todoItemStore.GetList());
サンプル コードは、todo 項目の一覧を返します。 前のコードで 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で使用される既定の形式は ON ですJS。 コンテンツ ネゴシエーションの説明を以下に示します。
- 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);
前のコードでは、有効な todo アイテムの要求から応答が 200 OK
返されます。 無効な todo アイテムに対する要求は、応答を 204 No Content
返します。
Accept ヘッダー
コンテンツ "ネゴシエーション" は、Accept
ヘッダーが要求に含まれるときに発生します。 要求に Accept ヘッダーが含まれるとき、ASP.NET Core は次のように処理します。
- Accept ヘッダーのメディアの種類を優先順で列挙します。
- 指定された形式のいずれかで応答を生成できるフォーマッタを見つけようとします。
クライアントの要求を満たすことができるフォーマッタが見つからない場合は、ASP.NET Core は次のようにします。
- MvcOptions.ReturnHttpNotAcceptable が
true
に設定されている場合は、406 Not Acceptable
を返します。 - 応答を生成できる最初のフォーマッタを見つけようとします。
要求された形式に対応するフォーマッタが構成されていない場合、オブジェクトを書式設定できる最初のフォーマッタが使用されます。 要求に Accept
ヘッダーが表示されない場合は、次のようになります。
- オブジェクトを処理できる最初のフォーマッタが使用されて、応答をシリアル化します。
- ネゴシエーションは発生しません。 サーバーが返す形式を決定します。
Accept ヘッダーに */*
が含まれる場合、RespectBrowserAcceptHeader
が MvcOptions で true に設定されていない限り、ヘッダーが無視されます。
ブラウザーとコンテンツ ネゴシエーション
一般的な API クライアントとは異なり、Web ブラウザーは Accept
ヘッダーを提供します。 Web ブラウザーでは、ワイルドカードを含む多くの形式が指定されています。 既定では、要求がブラウザーから送信されていることをフレームワークが検出すると、次のようになります。
Accept
ヘッダーは無視されます。- 特に構成されていない限り、コンテンツは ON で JS返されます。
この方法では、API を使用する際にブラウザー間でより一貫性のあるエクスペリエンスが提供されます。
ブラウザーでヘッダーを受け入れるようにアプリを構成するには、 プロパティを RespectBrowserAcceptHeader に true
設定します。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
options.RespectBrowserAcceptHeader = true;
});
フォーマッタの構成
追加の形式をサポートする必要があるアプリでは、適切な NuGet パッケージを追加し、サポートを構成できます。 入力と出力で別々のフォーマッタがあります。 入力フォーマッタは、モデル バインドによって使用されます。 出力フォーマッタは、応答の書式設定に使用されます。 カスタム フォーマッタの作成の詳細については、カスタム フォーマッタに関するページを参照してください。
XML 形式のサポートを追加する
を使用して実装された XML フォーマッタを XmlSerializer構成するには、 を呼び出します AddXmlSerializerFormatters。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddXmlSerializerFormatters();
前のコードを使用する場合、コントローラー メソッドは要求の Accept
ヘッダーに基づいて適切な形式を返します。
ベースのフォーマッタを構成 System.Text.Json
する
ベースのフォーマッタの機能を System.Text.Json
構成するには、 を使用 Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptionsします。 次の強調表示されたコードは、既定の camelCase 書式設定ではなく、PascalCase の書式設定を構成します。
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 });
ベースJSの ON 形式のサポートを追加Newtonsoft.Json
する
既定の ON フォーマッタでは、 が使用System.Text.Json
されますJS。 ベースのフォーマッタを Newtonsoft.Json
使用するには、NuGet パッケージを Microsoft.AspNetCore.Mvc.NewtonsoftJson
インストールし、 で Program.cs
構成します。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddNewtonsoftJson();
前のコードでは、AddNewtonsoftJson
を呼び出すことで、次の Web API、MVC、Razor Pages の各機能が、Newtonsoft.Json
を使用するように構成されます。
- ON の読み取りと書き込 JSみを行う入力フォーマッタと出力フォーマッタ
- 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 に設定されている場合でも、応答は常にキャメルケースです。 ProblemDetails
は、小文字を指定する RFC 7807 に従います。
属性が[ApiController]
コントローラー クラスに適用されると、モデルの検証が失敗したときにコントローラーによって応答が作成ValidationProblemDetailsされます。 この応答には、モデルのプロパティ名をエラー キーとして使用するディクショナリが含まれます。これは変更されません。 たとえば、次のモデルには、検証を必要とする 1 つのプロパティが含まれています。
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 追加します。 次の例では、SystemTextJsonValidationMetadataProvider
既定で System.Text.Json
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."
]
}
}
を使用して応答をValidationProblemDetails
書式設定するには、 を使用しますNewtonsoftJsonValidationMetadataProvider
。Newtonsoft.Json
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]
フィルターでは以下の処理が行われます。
- コントローラー内のすべてのアクションに対して、POC (Plain Old CLR Objects) またはそのObjectResult派生型に対する ON 形式の応答を強制的に返JSします。
- 他のフォーマッタが構成されていて、クライアントが別の形式を指定している場合でも、ON 形式の応答を返 JSします。
詳細については、フィルターに関するページを参照してください。
特殊なケースのフォーマッタ
一部の特殊なケースが組み込みのフォーマッタで実装されます。 既定では、戻り値の型 string
は text/plain として書式設定されます (Accept
ヘッダー経由で要求された場合は 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
がない場合、組み込みの ON フォーマッタ形式string
はJS型を返します。 組み込みの JSON フォーマッタが削除され、XML フォーマッタが使用可能な場合、XML フォーマッタ形式 string
は型を返します。 それ以外の場合は、戻り値の型 string
で 406 Not Acceptable
が返されます。
HttpNoContentOutputFormatter
がない場合、構成されているフォーマッタを利用し、null オブジェクトが書式設定されます。 次に例を示します。
- ON フォーマッタは JS、 の本文
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 |
JSON フォーマッタ (構成されている場合) |
/api/todoitems/5.xml |
XML フォーマッタ (構成される場合) |
ポリモーフィックな逆シリアル化
組み込み機能では、ポリモーフィックなシリアル化は限られた範囲で提供されていますが、逆シリアル化はまったくサポートされていません。 逆シリアル化を行うには、カスタム コンバーターが必要です。 ポリモーフィック逆シリアル化の完全なサンプルについては、「ポリモーフィック逆シリアル化」を参照してください。
その他のリソース
- サンプル コードを表示またはダウンロードします (ダウンロード方法)。