ちょっと話してnet core MVC2.1奥のApiControllerAttribute

5487 ワード

まず文章のリンクを貼る


本文


ASP.NET Core MVC 2.1はHTTP APIの構築にいくつかの小さな特性を提供し、今日の主役はApiControllerAttributeである.(注:文章は18年2月なのでcore 2.1はまだ発表されていません).

0.ApiControllerAttribute ControllerAttributeから継承


ASP.NET Core MVCにはすでにController Attributeがあり、これはタイプがControllerであるかどうかを示すために使用されます.表記したフレームワークでは、システム内のControllerとは何かがわかります.(フレームワークはプログラム内のControllerを取得する他の方法もあるので、このController Attributeは必須ではありません).ApiControllerAttributeControllerAttributeのサブクラスであるため、フレームワークはController発見を処理する際にControllerAttributeの表示の対象と同じである.
しかしながら、ApiControllerAttributeIApiBehaviorMetadataインターフェースを実装するので、HTTP Apiを出発点とするいくつかの追加の特性を提供する.これらの特性について説明します.

1.自動モデル状態検証


これはポイントです.フレームワークはモデルのstate、つまりModelStateを自動的に検証します.(注:でも私はFluentValidationを使っている間にモデル検証が役に立たなくて問題があったので、この文章を見つけました).
フレームワークは、ModelStateInvalidFilterを自動的に登録します.これはOnActionExecutingイベントで実行されます(具体的には、actionが実行される前にmodelがバインドされた後).彼の内部ではModelStateがValidかどうかをチェックし、InValidの場合は400 BadRequestを直接返します.これにより、後のコードを実行する必要がなくなり、効率が向上します.
モデルstateをresponseに自動的に配置し、content typeはapplication/problem+jsonです.もちろんカスタマイズすることもできます.結局、自分の検証があるので、後で話します.
次に、例を挙げてみましょう.
  • 以前の表記
  • [Route("[controller]")]
    public class BookController : Controller
    {
        [HttpPost("")]
        public IActionResult PostBook([FromBody]Book book)
        {
            if (ModelState.IsValid) //    
            {
                return BadRequest(ModelState);
            }
            //    。。。
        }
    }
  • 今このように書くことができます
  • [ApiController]
    [Route("[controller]")]
    public class BookController : Controller
    {
        [HttpPost("")]
        public IActionResult PostBook(Book book)
        {
            //   ,    modelstate
        }
    }

    ちなみに、ModelStateInvalidFilterは共通クラスなので、ApiControllerAttributeでなくても使えます.

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


    もう1つの非常に有用な特性はaction内のパラメータのモデルバインドが自動的に推定できることである.
    ASP.NET Core MVCには、パラメータに[FromBody]という特性を手動で指定して、Request bodyから逆シーケンス化する方法をシステムに知らせる必要があります.例えば、逆シーケンス化jsonです.そのため、この問題を解決するためにサードパーティのライブラリがたくさん書かれています.例えば、
  • WebApiContrib.Core.Formatter.Bson
  • WebApiContrib.Core.Formatter.Csv
  • その他は書かないで、例
  • を挙げます
    これで、これらは自動的に解決できます.
    それ以外に、1つのパラメータがrouteで定義されている場合、彼は自動的にpath、つまりurlからバインドを試み、だめならクエリーパラメータからバインドします.IFormFlieは、formフォーム上のバインドからデフォルトで取得されます.
    コードを次に示します.
  • より前の
  • [Route("[controller]")]
    public class BookController : Controller
    {
        [HttpPost("")]
        public IActionResult PostBook([FromBody]Book book)
        {
            //    
        }
    }
  • 現在
  • [ApiController]
    [Route("[controller]")]
    public class BookController : Controller
    {
        [HttpPost("")]
        public IActionResult PostBook(Book book)//FromBody     
        {
            //    
        }
    }

    3.multipart/form-dataリクエストの処理


    actionのパラメータが[FromFile]のプロパティ(通常はファイルアップロード用)を指定している場合、フレームワークは要求がmultipart/form-dataであると自動的に仮定します.これはコミュニティで提起されたこの問題を解決するために使われています.
    しかし、これもオプションで、自分でactionで[Consumes(...)]を定義すればいいです.

    4.その他


    2つの注意点があります.
  • ApiExplorerの可視性.デフォルトのすべてのコントローラはApiExplorerに対して表示されるので、swaggerなどの生成には影響しません.
  • は、特性に基づくルーティングにすぎない.集中的ルーティングメカニズムはAPI controllerに適用されず、フレームワークは、プロパティベースのルーティング、すなわちaction上で[Route("XXX")]を指定する方法のみを使用することを要求する.

  • 5.動作のカスタマイズ


    MVCフレームワークのほとんどのコンポーネントのように、ApiControllerAttributeの動作は高度にカスタマイズ可能である.まず、上記のほとんどの内容は簡単にon/offで切り替えることができます.
    具体的な設定はstartupメソッドでApiBehaviorOptionsで実現されていますが、まずこのクラスを見てみましょう.
        public class ApiBehaviorOptions
        {
            public Func InvalidModelStateResponseFactory { get; set; }
    
            public bool SuppressModelStateInvalidFilter { get; set; }
    
            public bool SuppressInferBindingSourcesForParameters { get; set; }
    
            public bool SuppressConsumesConstraintForFormFileParameters { get; set; }
        }

    すべてのboolタイプのプロパティのデフォルトはfalseです.Suppresは止める意味があります.以下の方法で設定できます.
    services.Configure(options =>
    {
        options.SuppressModelStateInvalidFilter = true;
        options.SuppressConsumesConstraintForFormFileParameters = true;
    });
    InvalidModelStateResponseFactoryのプロパティを見てみましょう.彼はIActionResultを返すFuncです.彼を通じて、私たちは自分の依頼を注入して必要な戻りタイプを実現することができます.例を挙げます.
    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.cnblogs.com/sheldon-lou/p/9495377.html