ApiControllerAttributeとそのASPを探索する.NET Core MVC 2.1の機能(カスタム戻りデータフォーマット)


ASP.NET Core MVC 2.1には、HTTP APIを構築するApiControllerAttribute向けの小さな機能が付属します.2.1の安定したバージョンはまだここにありませんが、この機能が何をしているのか、Web APIの作成にどのように役立つのかを見ることができます.
 

ApiControllerAttribute:ControllerAttribute


ASP.NET Core MVCにはすでにControllerAttributeという属性があります.特定のタイプをコントローラ候補として注釈するために使用されるため、フレームワークはタイプの方法を使用して潜在的なエンドポイントを発見します(フレームワークには他のコントローラ発見方法もあるので、属性は必要ありません).
ApiControllerAttributeは、実際にはControllerAttributeのサブクラスであるため、タイプを使用すると、コントローラの検出プロセスに同じ方法でタイプを強制します.
しかし、ApiControllerAttributeがIApiBehaviorMetadataというインタフェースを実装しているため、追加の機能も提供されています.このフレームワークは、IApiBehaviorMetadata注釈を使用する各タイプについて、HTTP APIを中心とした追加の機能を提供する.これらは以下で議論する.

自動モデルステータス検証


これは大きな問題です.このフレームワークでは、モデルのステータスが自動的に検証されます.これはマイクロソフトの各種ASPに基づくものです.NETのフレームワークの中の一つの問題は、永遠に.あなたはいつも手動が必要です.もしあなたがずっとこのブログを読んでいたら、私は過去にブログにこの文章を書いたことがあります.
この場合、フレームワークは自動的に何をしますか.ModelStateInvalidFilterを登録します.これはOnActionExecutingイベント中に実行されます(したがって、操作を実行する前にモデルバインド後).ModelStateが有効かどうかを内部で確認し、呼び出し元に400 Bad Request応答(ショート)をすぐに生成します.
応答を構築する方法は、モデル状態が応答に簡単に埋め込まれ、割り当てられたコンテンツタイプがアプリケーション/problem+jsonである.独自の認証デバイスを登録できるため、カスタマイズする機会があります(後で詳しく説明します).
総じて、この機能は次のコードを意味します.
[Route("[controller]")]
public class BookController : Controller
{
    [HttpPost("")]
    public IActionResult PostBook([FromBody]Book book)
    {
        if (ModelState.IsValid) 
        {
            return BadRequest(ModelState);
        }
        
        // omitted for brevity
    }
}

このコード・セグメントは、完全に同じ動作(モデル・ステータスの自動検証)を持つため、簡略化できます.
[ApiController]
[Route("[controller]")]
public class BookController : Controller
{
    [HttpPost("")]
    public IActionResult PostBook(Book book)
    {
        // omitted from brevity
    }
}

追加する価値のあることは、ModelStateInvalidFilterは共通クラスであり、ApiControllerAttributeを選択しなくてもMVC構成で自由に使用できる(例えば、MvcOptions用のグローバルフィルタとして挿入される)ことです.

パラメータバインドポリシーの自動推定


Web APIが開発したもう一つの非常に有用な機能は、操作のさまざまなパラメータがバインドモデルを自動的に推定することです.
ASP.NET Core MVCの最大の悩みの1つは、[FromBody]プロパティを使用して手動でコメント操作を行う必要がある複雑なパラメータであり、要求ボディからの逆シーケンス化をサポートする必要があります.例えば、JSONペイロードです.したがって、この問題を解決するために、さまざまなサードパーティソリューションが作成されています.自動処理します.
また、パスにパラメータが存在する場合は、自動的にパスバインドと推定されます.そうでない場合は、クエリー文字列パラメータと仮定します.ItormFileパラメータは、フォームから自動的にバインドされます.
これはもう必要ありません
[Route("[controller]")]
public class BookController : Controller
{
    [HttpPost("")]
    public IActionResult PostBook([FromBody]Book book)
    {
        // omitted from brevity
    }
}

これで(やっと!)箱を開けてすぐ使う:
[ApiController]
[Route("[controller]")]
public class BookController : Controller
{
    [HttpPost("")]
    public IActionResult PostBook(Book book)
    {
        // omitted from brevity
    }
}

Multipart/form-dataリクエストの使用


操作上のパラメータが[FormFile]プロパティを使用してコメントされている場合(通常はファイルのアップロードが完了している)、フレームワークは、エンドポイントがmultipart/form-data要求を使用していると自動的に仮定します.これにより、手動操作の手間が省けます.
操作上で自分の[Consumes(...)]を定義した場合を選択します.この場合、お客様の価値が優先されます.

その他


その他のメモ:
  • ApiExplorer知名度-各コントローラはデフォルトで使用可能なApiExplorerです.これはApiExplorer上に構築されたすべての機能、例えばSwagger生成に自動的に関与することを意味する.
  • は、APIコントローラには、属性ルーティング-集中ルーティングメカニズムのみが適用されません.このフレームワークでは、プロパティルーティングのみを使用する必要があります.

  • カスタム動作


    MVCフレームワークのほとんどと同様に、ApiControllerAttributeの開梱・即用動作は高度にカスタマイズ可能である.まず、上記の主な機能のほとんどがオン/オフできます.
    これは、アプリケーションの起動時にApiBehaviorOptionsで完了します.オプションの種類は次のとおりです.
     public class ApiBehaviorOptions
        {
            public Func InvalidModelStateResponseFactory { get; set; }
     
            public bool SuppressModelStateInvalidFilter { get; set; }
     
            public bool SuppressInferBindingSourcesForParameters { get; set; }
     
            public bool SuppressConsumesConstraintForFormFileParameters { get; set; }
        }

    デフォルトでは、すべてのブールフラグがfalseに設定されています.必要に応じて、次のように構成できます.
    services.Configure(options =>
    {
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressConsumesConstraintForFormFileParameters = true;
    });

    オプション構成では、現在のActionContextを取得し、独自のIActionResultを生成する独自のモデル検証依頼を注入できます.以下に、ModelStateに依存しているが、独自のカスタムレスポンスタイプにプロジェクトを投影する例を示します.
    services.Configure(options =>
    {
        options.InvalidModelStateResponseFactory = actionContext => 
        {
            var errors = actionContext.ModelState
                .Where(e => e.Value.Errors.Count > 0)
                .Select(e => new Error
                {
                Name = e.Key,
                Message = e.Value.Errors.First().ErrorMessage
                }).ToArray();
     
            return new BadRequestObjectResult(errors);
        }
    });
     
    class Error
    {
        public string Name { get; set; }
     
        public string Message { get; set; }
    }

    原文:https://www.strathweb.com/2018/02/exploring-the-apicontrollerattribute-and-its-features-for-asp-net-core-mvc-2-1/