Web API(Asp.net Core 2.1)から標準化されたエラー応答のみを返したいのですが、モデルバインディングエラーを処理する方法がわかりません。
プロジェクトは、「ASP.NET Core Web Application」>「API」テンプレートから作成されたばかりです。私は次のように定義されたシンプルなアクションを持っています:
[Route("[controller]")]
[ApiController]
public class MyTestController : ControllerBase
{
[HttpGet("{id}")]
public ActionResult<TestModel> Get(Guid id)
{
return new TestModel() { Greeting = "Hello World!" };
}
}
public class TestModel
{
public string Greeting { get; set; }
}
無効なGUID(たとえば、https://localhost:44303/MyTest/asdf
)を使用してこのアクションにリクエストを行うと、次の応答が返されます。
{
"id": [
"The value 'asdf' is not valid."
]
}
Startup.Configure
に次のコードがあります:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
JsonErrorMiddleware.CreateSingleton(env);
if (!env.IsDevelopment())
{
app.UseHsts();
}
app
.UseHttpsRedirection()
.UseStatusCodePages(async ctx => { await JsonErrorMiddleware.Instance.Invoke(ctx.HttpContext); })
.UseExceptionHandler(new ExceptionHandlerOptions() { ExceptionHandler = JsonErrorMiddleware.Instance.Invoke })
.UseMvc()
}
JsonErrorMiddleware
は、エラーを正しい形状に変換して返すようにし、それらを応答に入れるクラスです。モデルバインディングエラーではまったく呼び出されません(Exception
はスローされず、UseStatusCodePages
は呼び出されません)。
モデルバインディングにフックして、プロジェクトのすべてのアクションで標準化されたエラー応答を提供するにはどうすればよいですか?
たくさんの記事を読みましたが、それらはすべて、グローバルな例外処理または検証エラーについて議論しているようです。
ASP.NET Core 2.1が_[ApiController]
_属性を追加したことは注目に値します。この属性は、特に、渡されたBadRequestObjectResult
でModelState
を返すことでモデル検証エラーを自動的に処理します。 、コントローラーをその属性で装飾する場合、if (!ModelState.IsValid)
チェックを行う必要はなくなりました。
さらに、機能も拡張可能です。 Startup
では、次を追加できます。
_services.Configure<ApiBehaviorOptions>(o =>
{
o.InvalidModelStateResponseFactory = actionContext =>
new BadRequestObjectResult(actionContext.ModelState);
});
_
上記はすでにデフォルトで行われていることですが、InvalidModelStateResponseFactory
が設定されているラムダをカスタマイズして、好きなものを返すことができます。