ASP.NET Core Web API の応答データの書式設定Format response data in ASP.NET Core Web API

作成者: Steve SmithBy Steve Smith

ASP.NET Core MVC には、応答データを書式設定するためのサポートが組み込まれています。固定の書式を利用するか、クライアントの仕様に合わせます。ASP.NET Core MVC has built-in support for formatting response data, using fixed formats or in response to client specifications.

サンプル コードを表示またはダウンロードします (ダウンロード方法)。View or download sample code (how to download)

書式固有アクションの結果Format-Specific Action Results

アクションの結果には、JsonResultContentResult のように、特定の形式に固有となる型があります。Some action result types are specific to a particular format, such as JsonResult and ContentResult. アクションは、常に特定の方法で書式設定された結果を返すことができます。Actions can return specific results that are always formatted in a particular manner. たとえば、JsonResult を返すとき、クライアントの設定に関係なく、JSON で書式設定されたデータが返されます。For example, returning a JsonResult will return JSON-formatted data, regardless of client preferences. 同様に、ContentResult を返すとき、プレーンテキストで書式設定された文字列データが返されます (単純に文字列が返されます)。Likewise, returning a ContentResult will return plain-text-formatted string data (as will simply returning a string).

注意

特定の型を返すためにアクションは必要ありません。MVC ではあらゆるオブジェクト戻り値を利用できます。An action isn't required to return any particular type; MVC supports any object return value. アクションが IActionResult 実装を返し、コントローラーが Controller から継承する場合、開発者は選択肢の多くに対応するさまざまなヘルパー メソッドを利用できます。If an action returns an IActionResult implementation and the controller inherits from Controller, developers have many helper methods corresponding to many of the choices. 型が IActionResult ではないオブジェクトを返すアクションからの結果は、適切な IOutputFormatter 実装を利用してシリアル化されます。Results from actions that return objects that are not IActionResult types will be serialized using the appropriate IOutputFormatter implementation.

Controller 基底クラスから継承するコントローラーから特定の書式でデータを返すには、組み込みのヘルパー メソッド Json を使用して JSON を返し、Content を使用してプレーンテキストを返します。To return data in a specific format from a controller that inherits from the Controller base class, use the built-in helper method Json to return JSON and Content for plain text. アクション メソッドでは、特定の結果の型を返す必要があります (JsonResultIActionResult など)。Your action method should return either the specific result type (for instance, JsonResult) or IActionResult.

JSON で書式設定されたデータを返す:Returning JSON-formatted data:

// GET: api/authors
[HttpGet]
public JsonResult Get()
{
    return Json(_authorRepository.List());
}

このアクションからのサンプル応答:Sample response from this action:

Microsoft Edge の開発者ツールの [ネットワーク] タブ。応答のコンテンツの種類が application/json です。

応答のコンテンツの種類が application/json であることに注目してください。ネットワーク要求の一覧と [応答ヘッダー] セクションの両方に表示されます。Note that the content type of the response is application/json, shown both in the list of network requests and in the Response Headers section. また、ブラウザー (この場合、Microsoft Edge) により [応答ヘッダー] セクションの Accept ヘッダーに表示されるオプションの一覧に注目してください。Also note the list of options presented by the browser (in this case, Microsoft Edge) in the Accept header in the Request Headers section. 現在の手法ではこのヘッダーが無視されます。無視しない方法について以下で説明します。The current technique is ignoring this header; obeying it is discussed below.

プレーンテキストで書式設定されたデータを返すには、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.");
}

このアクションからの応答:A response from this action:

Microsoft Edge の開発者ツールの [ネットワーク] タブ。応答のコンテンツの種類が text/plain です。

この場合、返される Content-Typetext/plain です。Note in this case the Content-Type returned is text/plain. 応答の型として文字列を使用する方法でもこれと同じ動作が得られます。You can also achieve this same behavior using just a string response type:

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

ヒント

戻り値の型やオプションを複数ともなう重要なアクションの場合 (実行された操作の結果に基づき、さまざまな HTTP ステータス コードが生成されるなど)、戻り値の型として IActionResult を優先します。For non-trivial actions with multiple return types or options (for example, different HTTP status codes based on the result of operations performed), prefer IActionResult as the return type.

コンテンツ ネゴシエーションContent Negotiation

クライアントにより Accept ヘッダーが指定されると、コンテンツ ネゴシエーション (省略形は conneg) が発生します。Content negotiation (conneg for short) occurs when the client specifies an Accept header. ASP.NET Core MVC で使用される既定の書式は JSON です。The default format used by ASP.NET Core MVC is JSON. コンテンツ ネゴシエーションは ObjectResult によって実装されます。Content negotiation is implemented by ObjectResult. (すべて ObjectResult に基づく) ヘルパー メソッドから返されるステータス コード固有のアクションの結果にも組み込まれます。It's also built into the status code specific action results returned from the helper methods (which are all based on ObjectResult). モデルの型を返すこともできます (データ転送の型として定義しているクラス)。フレームワークはこれを自動的に ObjectResult でラップします。You can also return a model type (a class you've defined as your data transfer type) and the framework will automatically wrap it in an ObjectResult for you.

次のアクション メソッドでは、ヘルパー メソッドの 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 = _authorRepository.GetByNameSubstring(namelike);
    if (!result.Any())
    {
        return NotFound(namelike);
    }
    return Ok(result);
}

別の書式が要求され、その要求された書式をサーバーが返せる場合を除き、JSON で書式設定された応答が返されます。A JSON-formatted response will be returned unless another format was requested and the server can return the requested format. Fiddler のようなツールを利用し、Accept ヘッダーを含む要求を作成したり、別の書式を指定したりできます。You can use a tool like Fiddler to create a request that includes an Accept header and specify another format. その場合、要求された書式で応答を生成できるフォーマッタがサーバーに与えられている場合、クライアントの優先書式で結果が返されます。In that case, if the server has a formatter that can produce a response in the requested format, the result will be returned in the client-preferred format.

Fiddler コンソールに手動で作成された GET 要求が表示されているのを確認できます。Accept ヘッダー値が application/xml になっています。

上のスクリーンショットでは、要求の生成に Fiddler Composer が使用されています。Accept: application/xml を指定しています。In the above screenshot, the Fiddler Composer has been used to generate a request, specifying Accept: application/xml. 既定では、ASP.NET Core MVC は JSON のみに対応しています。そのため、別の書式が指定されていても、結果は JSON で書式設定されて返されます。By default, ASP.NET Core MVC only supports JSON, so even when another format is specified, the result returned is still JSON-formatted. フォーマッタの追加方法は次のセクションで確認します。You'll see how to add additional formatters in the next section.

コントローラー アクションでは、POCO (Plain Old CLR Object/単純な従来の CLR オブジェクト) を返すことができます。この場合、ASP.NET Core MVC によって、オブジェクトをラップする ObjectResult が自動的に作成されます。Controller actions can return POCOs (Plain Old CLR Objects), in which case ASP.NET Core MVC automatically creates an ObjectResult for you that wraps the object. 書式設定され、シリアル化されたオブジェクトがクライアントに与えられます (JSON 書式が既定ですが、XML やその他の形式を設定できます)。The client will get the formatted serialized object (JSON format is the default; you can configure XML or other formats). 返されるオブジェクトが null の場合、フレームワークは 204 No Content 応答を返します。If the object being returned is null, then the framework will return a 204 No Content response.

オブジェクトの型を返す:Returning an object type:

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

このサンプルでは、有効な作成者エイリアスを要求しています。200 OK という応答と作成者のデータが返されます。In the sample, a request for a valid author alias will receive a 200 OK response with the author's data. 無効なエイリアスを要求すると、204 No Content という応答が返されます。A request for an invalid alias will receive a 204 No Content response. 下のスクリーンショットでは、XML 形式と JSON 形式の応答を確認できます。Screenshots showing the response in XML and JSON formats are shown below.

コンテンツ ネゴシエーション プロセスContent Negotiation Process

コンテンツ ネゴシエーションは、Accept ヘッダーが要求に現れるときにのみ発生します。Content negotiation only takes place if an Accept header appears in the request. 要求に Accept ヘッダーが含まれると、フレームワークは Accept ヘッダーのメディアの種類を優先順序で列挙し、Accept ヘッダーによって指定される書式の 1 つで応答を生成できるフォーマットを探します。When a request contains an accept header, the framework will enumerate the media types in the accept header in preference order and will try to find a formatter that can produce a response in one of the formats specified by the accept header. クライアントの要求を満たせるフォーマッタが見つからない場合、フレームワークは、応答を生成できる最初のフォーマットを見つけようとします (406 Not Acceptable を代わりに返すよう、開発者が MvcOptions でオプションを構成していない限り)。In case no formatter is found that can satisfy the client's request, the framework will try to find the first formatter that can produce a response (unless the developer has configured the option on MvcOptions to return 406 Not Acceptable instead). 要求で XML が指定されているが、XML フォーマッタが構成されていない場合、JSON フォーマッタが使用されます。If the request specifies XML, but the XML formatter has not been configured, then the JSON formatter will be used. もっと一般的に言うと、要求された書式を提供できるフォーマッタが構成されていない場合、オブジェクトを書式設定できる最初のフォーマッタが使用されます。More generally, if no formatter is configured that can provide the requested format, then the first formatter that can format the object is used. ヘッダーが与えられない場合、応答のシリアル化に、返すオブジェクトを処理できる最初のフォーマッタが使用されます。If no header is given, the first formatter that can handle the object to be returned will be used to serialize the response. この例では、ネゴシエーションは発生しません。使用する書式はサーバーが決定します。In this case, there isn't any negotiation taking place - the server is determining what format it will use.

注意

Accept ヘッダーに */* が含まれる場合、RespectBrowserAcceptHeaderMvcOptions で true に設定されていない限り、ヘッダーが無視されます。If the Accept header contains */*, the Header will be ignored unless RespectBrowserAcceptHeader is set to true on MvcOptions.

ブラウザーとコンテンツ ネゴシエーションBrowsers and Content Negotiation

一般的な API クライアントとは異なり、Web ブラウザーは、ワイルドカードなど、多大な書式を含む Accept ヘッダーを提供することが多々あります。Unlike typical API clients, web browsers tend to supply Accept headers that include a wide array of formats, including wildcards. 既定では、ブラウザーから要求が来ていることをフレームワークが検出すると、フレームワークは Accept ヘッダーを無視し、代わりにアプリケーションで構成されている既定の書式でコンテンツを返します (他が設定されていない場合は JSON)。By default, when the framework detects that the request is coming from a browser, it will ignore the Accept header and instead return the content in the application's configured default format (JSON unless otherwise configured). さまざまなブラウザーで API を利用しても、一貫した操作性が与えられます。This provides a more consistent experience when using different browsers to consume APIs.

アプリケーションでブラウザーの Accept ヘッダーを受け付けるようにする場合、MVC の構成の一部として設定できます。Startup.csConfigureServices メソッドで RespectBrowserAcceptHeadertrue に設定します。If you would prefer your application honor browser accept headers, you can configure this as part of MVC's configuration by setting RespectBrowserAcceptHeader to true in the ConfigureServices method in Startup.cs.

services.AddMvc(options =>
{
    options.RespectBrowserAcceptHeader = true; // false by default
});

フォーマッタを構成するConfiguring Formatters

アプリケーションが既定の JSON 以外の追加書式をサポートしなければならない場合、NuGet パッケージを追加し、サポートするように MVC を構成できます。If your application needs to support additional formats beyond the default of JSON, you can add NuGet packages and configure MVC to support them. 入力と出力で別々のフォーマッタがあります。There are separate formatters for input and output. 入力フォーマッタはモデル バインディングで使用されます。出力フォーマッタは応答の書式設定に使用されます。Input formatters are used by Model Binding; output formatters are used to format responses. カスタム フォーマッタを構成することもできます。You can also configure Custom Formatters.

XML 形式のサポートを追加するAdding XML Format Support

XML 書式設定のサポートを追加するには、Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet パッケージをインストールします。To add support for XML formatting, install the Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet package.

Startup.cs で MVC の構成に XmlSerializerFormatters を追加します。Add the XmlSerializerFormatters to MVC's configuration in Startup.cs:

services.AddMvc()
    .AddXmlSerializerFormatters();

あるいは、出力フォーマッタだけを追加できます。Alternately, you can add just the output formatter:

services.AddMvc(options =>
{
    options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});

以上の 2 つの手法では、System.Xml.Serialization.XmlSerializer を利用して結果がシリアル化されます。These two approaches will serialize results using System.Xml.Serialization.XmlSerializer. System.Runtime.Serialization.DataContractSerializer がよければ、それを利用できます。それに関連するフォーマッタを追加してください。If you prefer, you can use the System.Runtime.Serialization.DataContractSerializer by adding its associated formatter:

services.AddMvc(options =>
{
    options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
});

XML 書式設定のサポートを追加すると、コントローラー メソッドは、要求の Accept ヘッダーに基づき、適切な書式を返すはずです。下の Fiddler の例をご覧ください。Once you've added support for XML formatting, your controller methods should return the appropriate format based on the request's Accept header, as this Fiddler example demonstrates:

Fiddler コンソール: 要求の [Raw] タブで、Accept ヘッダー値が application/xml であることを確認できます。

[Inspectors] タブで、Accept: application/xml ヘッダーが設定された状態で Raw GET 要求が行われたことを確認できます。You can see in the Inspectors tab that the Raw GET request was made with an Accept: application/xml header set. 応答ウィンドウに Content-Type: application/xml ヘッダーが表示されます。Author オブジェクトが XML にシリアル化されています。The response pane shows the Content-Type: application/xml header, and the Author object has been serialized to XML.

[Composer] タブを使用して要求を変更し、Accept ヘッダーに application/json を指定します。Use the Composer tab to modify the request to specify application/json in the Accept header. 要求を実行します。応答が JSON で書式設定されます。Execute the request, and the response will be formatted as JSON:

Fiddler コンソール: 要求の [Raw] タブで、Accept ヘッダー値が application/json であることを確認できます。

このスクリーンショットでは、Accept: application/json のヘッダーとして要求セットを確認できます。応答によって、その Content-Type と同じものが指定されます。In this screenshot, you can see the request sets a header of Accept: application/json and the response specifies the same as its Content-Type. Author オブジェクトは応答の本文に JSON 形式で表示されます。The Author object is shown in the body of the response, in JSON format.

特定の書式を強制するForcing a Particular Format

特定のアクションの応答書式を制限する場合、[Produces] フィルターを適用できます。If you would like to restrict the response formats for a specific action you can, you can apply the [Produces] filter. [Produces] フィルターによって、特定のアクション (またはコントローラー) の応答書式が指定されます。The [Produces] filter specifies the response formats for a specific action (or controller). ほとんどのフィルターと同様に、アクション、コントローラー、グローバル スコープで適用できます。Like most Filters, this can be applied at the action, controller, or global scope.

[Produces("application/json")]
public class AuthorsController

アプリケーションに他のフォーマッタが構成されており、クライアントが Accept ヘッダーで別の利用できる書式を要求している場合でも、[Produces] フィルターは AuthorsController 内のすべてのアクションに JSON で書式設定された応答を返すように強制します。The [Produces] filter will force all actions within the AuthorsController to return JSON-formatted responses, even if other formatters were configured for the application and the client provided an Accept header requesting a different, available format. フィルターをグローバルで適用する方法など、詳細については「フィルター」を参照してください。See Filters to learn more, including how to apply filters globally.

特殊なケースのフォーマッタSpecial Case Formatters

一部の特殊なケースが組み込みのフォーマッタで実装されます。Some special cases are implemented using built-in formatters. 既定では、戻り値の型 stringtext/plain として書式設定されます (Accept ヘッダー経由で要求された場合は text/html)。By default, string return types will be formatted as text/plain (text/html if requested via Accept header). この動作は TextOutputFormatter を削除することで削除できます。This behavior can be removed by removing the TextOutputFormatter. Startup.csConfigure メソッドでフォーマッタを削除します (下記参照)。You remove formatters in the Configure method in Startup.cs (shown below). 戻り値の型としてモデル オブジェクトをともなうアクションは、null を返すとき、204 No Content の応答を返します。Actions that have a model object return type will return a 204 No Content response when returning null. この動作は HttpNoContentOutputFormatter を削除することで削除できます。This behavior can be removed by removing the HttpNoContentOutputFormatter. 次のコードでは、TextOutputFormatterHttpNoContentOutputFormatter が削除されます。The following code removes the TextOutputFormatter and HttpNoContentOutputFormatter.

services.AddMvc(options =>
{
    options.OutputFormatters.RemoveType<TextOutputFormatter>();
    options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
});

TextOutputFormatter がない場合、string は戻り値の型として 406 Not Acceptable などを返します。Without the TextOutputFormatter, string return types return 406 Not Acceptable, for example. XML フォーマッタが存在するときは、TextOutputFormatter が削除された場合、戻り値の型 string が書式設定されます。Note that if an XML formatter exists, it will format string return types if the TextOutputFormatter is removed.

HttpNoContentOutputFormatter がない場合、構成されているフォーマッタを利用し、null オブジェクトが書式設定されます。Without the HttpNoContentOutputFormatter, null objects are formatted using the configured formatter. たとえば、JSON フォーマッタは応答と null の本文を返すのに対し、XML フォーマッタは空の XML 要素と属性 xsi:nil="true" セットを返します。For example, the JSON formatter will simply return a response with a body of null, while the XML formatter will return an empty XML element with the attribute xsi:nil="true" set.

応答形式の URL マッピングResponse Format URL Mappings

クライアントは URL の一部として特定の書式を要求できます。たとえば、クエリ文字列やパスの一部に含めます。あるいは、.xml や .json など、書式固有のファイル拡張子を利用します。Clients can request a particular format as part of the URL, such as in the query string or part of the path, or 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:

[FormatFilter]
public class ProductsController
{
    [Route("[controller]/[action]/{id}.{format?}")]
    public Product GetById(int id)

このルートにより、要求された書式をオプションのファイル拡張子として指定できます。This route would allow 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 will map the response format to the appropriate formatter when the response is created.

ルートRoute フォーマッタFormatter
/products/GetById/5 既定の出力フォーマッタThe default output formatter
/products/GetById/5.json JSON フォーマッタ (構成される場合)The JSON formatter (if configured)
/products/GetById/5.xml XML フォーマッタ (構成される場合)The XML formatter (if configured)