ASP.NET Core で Web API を構築するBuild web APIs with ASP.NET Core

作成者: Scott AddieBy Scott Addie

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

このドキュメントでは、ASP.NET Core での各機能を使用する最も適切な web API をビルドする方法について説明します。This document explains how to build a web API in ASP.NET Core and when it's most appropriate to use each feature.

ControllerBase からクラスを派生するDerive class from ControllerBase

Web API として機能することを目的としたコント ローラー内の ControllerBase クラスから継承します。Inherit from the ControllerBase class in a controller that's intended to serve as a web API. 例:For example:

[Produces("application/json")]
[Route("api/[controller]")]
public class PetsController : ControllerBase
{
    private readonly PetsRepository _repository;

    public PetsController(PetsRepository repository)
    {
        _repository = repository;
    }

    [HttpGet]
    public async Task<ActionResult<List<Pet>>> GetAllAsync()
    {
        return await _repository.GetPetsAsync();
    }

    [HttpGet("{id}")]
    [ProducesResponseType(404)]
    public async Task<ActionResult<Pet>> GetByIdAsync(int id)
    {
        var pet = await _repository.GetPetAsync(id);

        if (pet == null)
        {
            return NotFound();
        }

        return pet;
    }

    [HttpPost]
    [ProducesResponseType(400)]
    public async Task<ActionResult<Pet>> CreateAsync(Pet pet)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        await _repository.AddPetAsync(pet);

        return CreatedAtAction(nameof(GetByIdAsync),
            new { id = pet.Id }, pet);
    }
}
[Produces("application/json")]
[Route("api/[controller]")]
public class PetsController : ControllerBase
{
    private readonly PetsRepository _repository;

    public PetsController(PetsRepository repository)
    {
        _repository = repository;
    }

    [HttpGet]
    [ProducesResponseType(typeof(IEnumerable<Pet>), 200)]
    public async Task<IActionResult> GetAllAsync()
    {
        var pets = await _repository.GetPetsAsync();

        return Ok(pets);
    }

    [HttpGet("{id}")]
    [ProducesResponseType(typeof(Pet), 200)]
    [ProducesResponseType(404)]
    public async Task<IActionResult> GetByIdAsync(int id)
    {
        var pet = await _repository.GetPetAsync(id);

        if (pet == null)
        {
            return NotFound();
        }

        return Ok(pet);
    }

    [HttpPost]
    [ProducesResponseType(typeof(Pet), 201)]
    [ProducesResponseType(400)]
    public async Task<IActionResult> CreateAsync([FromBody] Pet pet)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        await _repository.AddPetAsync(pet);

        return CreatedAtAction(nameof(GetByIdAsync),
            new { id = pet.Id }, pet);
    }
}

ControllerBase クラスを使用すると、いくつかのプロパティとメソッドにアクセスできます。The ControllerBase class provides access to several properties and methods. 上のコードでは、例に BadRequest(ModelStateDictionary)CreatedAtAction(String, Object, Object) が含まれています。In the preceding code, examples include BadRequest(ModelStateDictionary) and CreatedAtAction(String, Object, Object). これらのメソッドはアクション メソッド内で呼び出され、HTTP 400 および 201 のステータス コードをそれぞれ返します。These methods are called within action methods to return HTTP 400 and 201 status codes, respectively. ModelState プロパティ (これも ControllerBase によって提供される) は、要求モデル検証を処理する場合にアクセスされます。The ModelState property, also provided by ControllerBase, is accessed to handle request model validation.

ApiController 属性を使用した注釈Annotation with ApiController attribute

ASP.NET Core 2.1 では、Web API コントローラー クラスを表す [ApiController] 属性が導入されました。ASP.NET Core 2.1 introduces the [ApiController] attribute to denote a web API controller class. 例:For example:

[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase

この属性をコントローラー レベルで使用するには、2.1 以降の互換性バージョン (SetCompatibilityVersion で設定) が必須です。A compatibility version of 2.1 or later, set via SetCompatibilityVersion, is required to use this attribute at the controller level. たとえば、Startup.ConfigureServices の強調表示されているコードでは、2.1 の互換性フラグが設定されます。For example, the highlighted code in Startup.ConfigureServices sets the 2.1 compatibility flag:

services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

詳細については、「ASP.NET Core MVC の互換バージョン」を参照してください。For more information, see ASP.NET Core MVC の互換バージョン.

ASP.NET Core 2.2 以降では、[ApiController] 属性をアセンブリに適用できます。In ASP.NET Core 2.2 or later, the [ApiController] attribute can be applied to an assembly. この方法での注釈では、アセンブリ内のすべてのコントローラーに Web API の動作が適用されます。Annotation in this manner applies web API behavior to all controllers in the assembly. 個々のコントローラーを有効にする方法はありません。Beware that there's no way to opt out for individual controllers. 推奨事項として、アセンブリ レベルの属性を Startup クラスに適用する必要があります。As a recommendation, assembly-level attributes should be applied to the Startup class:

[assembly: ApiController]
namespace WebApiSample.Api._22
{
    public class Startup
    {

この属性をアセンブリ レベルで使用するには、2.2 以降の互換性バージョン (SetCompatibilityVersion で設定) が必須です。A compatibility version of 2.2 or later, set via SetCompatibilityVersion, is required to use this attribute at the assembly level.

コントローラーの REST 固有の動作を有効にする場合、通常、[ApiController] 属性は ControllerBase と組み合わせて使用されます。The [ApiController] attribute is commonly coupled with ControllerBase to enable REST-specific behavior for controllers. ControllerBase では、NotFoundFile などのメソッドにアクセスできます。ControllerBase provides access to methods such as NotFound and File.

その他に、[ApiController] 属性で注釈が付けられたユーザー定義の基本コントローラー クラスを作成するという方法があります。Another approach is to create a custom base controller class annotated with the [ApiController] attribute:

[ApiController]
public class MyBaseController
{
}

次のセクションでは、属性によって追加される便利な機能について説明します。The following sections describe convenience features added by the attribute.

自動的な HTTP 400 応答Automatic HTTP 400 responses

モデル検証エラーが発生すると、HTTP 400 応答が自動的にトリガーされます。Model validation errors automatically trigger an HTTP 400 response. その結果、次のコードは実際のアクションでは不要になります。Consequently, the following code becomes unnecessary in your actions:

if (!ModelState.IsValid)
{
    return BadRequest(ModelState);
}

結果として発生する応答の出力をカスタマイズするには、InvalidModelStateResponseFactory を使用します。Use InvalidModelStateResponseFactory to customize the output of the resulting response.

アクションがモデル検証エラーから回復できる場合は、既定の動作を無効にすると便利です。Disabling the default behavior is useful when your action can recover from a model validation error. SuppressModelStateInvalidFilter プロパティが true に設定されている場合、既定の動作は無効になります。The default behavior is disabled when the SuppressModelStateInvalidFilter property is set to true. Startup.ConfigureServicesservices.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_<version_number>); の後ろに次のコードを追加します。Add the following code in Startup.ConfigureServices after services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_<version_number>);:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;

        options.ClientErrorMapping[404].Link = 
            "https://httpstatuses.com/404";
    });
services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

2.2 以降の互換性フラグを設定した場合の、HTTP 400 応答に対する既定の応答の種類は、ValidationProblemDetails です。With a compatibility flag of 2.2 or later, the default response type for HTTP 400 responses is ValidationProblemDetails. ValidationProblemDetails 型は RFC 7807 仕様に準拠しています。The ValidationProblemDetails type complies with the RFC 7807 specification. 代わりに ASP.NET Core 2.1 エラー形式の SerializableError を返すようにするには、SuppressUseValidationProblemDetailsForInvalidModelStateResponses プロパティを true に設定します。Set the SuppressUseValidationProblemDetailsForInvalidModelStateResponses property to true to instead return the ASP.NET Core 2.1 error format of SerializableError. Startup.ConfigureServices に次のコードを追加します。Add the following code in Startup.ConfigureServices:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options
          .SuppressUseValidationProblemDetailsForInvalidModelStateResponses = true;
    });

バインディング ソース パラメーター推論Binding source parameter inference

バインディング ソース属性では、アクション パラメーターの値が存在する場所が定義されます。A binding source attribute defines the location at which an action parameter's value is found. 次のバインディング ソース属性が存在します。The following binding source attributes exist:

属性Attribute バインド ソースBinding source
[FromBody][FromBody] 要求本文Request body
[FromForm][FromForm] 要求本文内のフォーム データForm data in the request body
[FromHeader][FromHeader] 要求ヘッダーRequest header
[FromQuery][FromQuery] 要求のクエリ文字列パラメーターRequest query string parameter
[FromRoute][FromRoute] 現在の要求からのルート データRoute data from the current request
[FromServices][FromServices] アクション パラメーターとして挿入される要求サービスThe request service injected as an action parameter

警告

値に %2f (つまり、/) が含まれる可能性がある場合は、[FromRoute] を使用しないでください。Don't use [FromRoute] when values might contain %2f (that is /). %2f/ にエスケープ解除されません。%2f won't be unescaped to /. 値に %2f が含まれる可能性がある場合は、[FromQuery] を使用してください。Use [FromQuery] if the value might contain %2f.

[ApiController] 属性がない場合は、バインディング ソース属性を明示的に定義します。Without the [ApiController] attribute, binding source attributes are explicitly defined. 次の例では、discontinuedOnly パラメーター値が要求 URL のクエリ文字列に指定されていることが [FromQuery] によって示されています。In the following example, the [FromQuery] attribute indicates that the discontinuedOnly parameter value is provided in the request URL's query string:

[HttpGet]
public async Task<ActionResult<List<Product>>> GetAsync(
    [FromQuery] bool discontinuedOnly = false)
{
    List<Product> products = null;

    if (discontinuedOnly)
    {
        products = await _repository.GetDiscontinuedProductsAsync();
    }
    else
    {
        products = await _repository.GetProductsAsync();
    }

    return products;
}

アクション パラメーターの既定のデータ ソースには推論規則が適用されます。Inference rules are applied for the default data sources of action parameters. これらの規則によって、アクション パラメーターに、通常、手動で適用する可能性の高いバインディング ソースが構成されます。These rules configure the binding sources you're otherwise likely to manually apply to the action parameters. バインディング ソースの属性は、次のように動作します。The binding source attributes behave as follows:

  • [FromBody] は複合型のパラメーターに対して推論されます。[FromBody] is inferred for complex type parameters. この規則には例外があり、IFormCollectionCancellationToken などの、特殊な意味を持つ複雑な組み込み型が該当します。An exception to this rule is any complex, built-in type with a special meaning, such as IFormCollection and CancellationToken. バインディング ソース推論コードでは、そのような特殊な型は無視されます。The binding source inference code ignores those special types. [FromBody] は、stringint などの単純型に対しては推論されません。[FromBody] isn't inferred for simple types such as string or int. そのため、その機能が必要な場合、単純型に対しては [FromBody] 属性を使用する必要があります。Therefore, the [FromBody] attribute should be used for simple types when that functionality is needed. アクションの複数のパラメーターが明示的に指定されている場合 ([FromBody] によって) または要求本文からバインドとして推論される場合は、例外がスローされます。When an action has more than one parameter explicitly specified (via [FromBody]) or inferred as bound from the request body, an exception is thrown. たとえば、次のアクション シグネチャは例外の原因となります。For example, the following action signatures cause an exception:
// Don't do this. All of the following actions result in an exception.
[HttpPost]
public IActionResult Action1(Product product, 
                             Order order) => null;

[HttpPost]
public IActionResult Action2(Product product, 
                             [FromBody] Order order) => null;

[HttpPost]
public IActionResult Action3([FromBody] Product product, 
                             [FromBody] Order order) => null;
  • [FromForm]IFormFile および IFormFileCollection 型のアクション パラメーターに対して推論されます。[FromForm] is inferred for action parameters of type IFormFile and IFormFileCollection. 簡易型またはユーザー定義型に対しては推論されません。It's not inferred for any simple or user-defined types.
  • [FromRoute] は、ルート テンプレート内のパラメーターと一致する任意のアクション パラメーター名に対して推論されます。[FromRoute] is inferred for any action parameter name matching a parameter in the route template. 複数のルートがアクション パラメーターと一致する場合、ルート値はいずれも [FromRoute] と見なされます。When more than one route matches an action parameter, any route value is considered [FromRoute].
  • [FromQuery] は他の任意のアクション パラメーターに対して推論されます。[FromQuery] is inferred for any other action parameters.

SuppressInferBindingSourcesForParameters プロパティが true に設定されている場合、既定の推論規則は無効になります。The default inference rules are disabled when the SuppressInferBindingSourcesForParameters property is set to true. Startup.ConfigureServicesservices.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_<version_number>); の後ろに次のコードを追加します。Add the following code in Startup.ConfigureServices after services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_<version_number>);:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;

        options.ClientErrorMapping[404].Link = 
            "https://httpstatuses.com/404";
    });
services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

マルチパート/フォーム データ要求の推論Multipart/form-data request inference

[FromForm] 属性を使用してアクション パラメーターに注釈を付けた場合は、multipart/form-data 要求コンテンツ型が推論されます。When an action parameter is annotated with the [FromForm] attribute, the multipart/form-data request content type is inferred.

SuppressConsumesConstraintForFormFileParameters プロパティが true に設定されている場合、既定の動作は無効になります。The default behavior is disabled when the SuppressConsumesConstraintForFormFileParameters property is set to true.

Startup.ConfigureServices に次のコードを追加します。Add the following code in Startup.ConfigureServices:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;

        options.ClientErrorMapping[404].Link = 
            "https://httpstatuses.com/404";
    });

Startup.ConfigureServicesservices.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); の後ろに次のコードを追加します。Add the following code in Startup.ConfigureServices after services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);:

services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressConsumesConstraintForFormFileParameters = true;
    options.SuppressInferBindingSourcesForParameters = true;
    options.SuppressModelStateInvalidFilter = true;
});

属性ルーティング要件Attribute routing requirement

属性ルーティングは要件になります。Attribute routing becomes a requirement. 例:For example:

[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase

UseMvc 内で定義されているか、または Startup.Configure 内の UseMvcWithDefaultRoute によって定義されている従来のルートを通してアクションにアクセスすることはできません。Actions are inaccessible via conventional routes defined in UseMvc or by UseMvcWithDefaultRoute in Startup.Configure.

エラー状態コードに対する問題の詳細の応答Problem details responses for error status codes

ASP.NET Core 2.2 以降では、MVC によってエラー結果 (状態コードが 400 以降の結果) が ProblemDetails による結果に変換されます。In ASP.NET Core 2.2 or later, MVC transforms an error result (a result with status code 400 or higher) to a result with ProblemDetails. ProblemDetails は次のようになります。ProblemDetails is:

  • RFC 7807 仕様に基づいた型。A type based on the RFC 7807 specification.
  • HTTP 応答でコンピューターが判読できるエラーの詳細を指定するための標準化された形式。A standardized format for specifying machine-readable error details in an HTTP response.

コントローラー アクションで次のコードがあるとします。Consider the following code in a controller action:

if (product == null)
{
    return NotFound();
}

NotFound の HTTP 応答には 404 状態コードと ProblemDetails の本文が含まれています。The HTTP response for NotFound has a 404 status code with a ProblemDetails body. 例:For example:

{
    type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
    title: "Not Found",
    status: 404,
    traceId: "0HLHLV31KRN83:00000001"
}

問題の詳細機能には、2.2 以降の互換性フラグが必要です。The problem details feature requires a compatibility flag of 2.2 or later. SuppressMapClientErrors プロパティが true に設定されている場合、既定の動作は無効になります。The default behavior is disabled when the SuppressMapClientErrors property is set to true. Startup.ConfigureServices に次のコードを追加します。Add the following code in Startup.ConfigureServices:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;

        options.ClientErrorMapping[404].Link = 
            "https://httpstatuses.com/404";
    });

ProblemDetails の応答の内容を構成するには、ClientErrorMapping プロパティを使用します。Use the ClientErrorMapping property to configure the contents of the ProblemDetails response. たとえば、次のコードにより、404 応答の type プロパティが更新されます。For example, the following code updates the type property for 404 responses:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressConsumesConstraintForFormFileParameters = true;
        options.SuppressInferBindingSourcesForParameters = true;
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressMapClientErrors = true;

        options.ClientErrorMapping[404].Link = 
            "https://httpstatuses.com/404";
    });

その他の技術情報Additional resources