ほとんどの例では、 ASP.NET MVC入力の検証は次のように行われます。
[HttpPost] public IActionResult Test(SomeParam param) { if (!ModelState.IsValid) { return View(param);
このコードは改善できます:
- メソッド本体から検証を削除し、
if (!ModelState.IsValid)
重複を取り除きif (!ModelState.IsValid)
- 応答コード422を返します
ActionFilterで検証を行う
ASP.NET MVCの承認は、属性を使用して構成されます。 類推によってそれを行い、検証のための属性を宣言しましょう:
public enum ValidationResult { View, Json } public class ValidationFilterAttribute: ActionFilterAttribute { private readonly ValidationResult _result; public ValidationFilterAttribute(ValidationResult result = ValidationResult.Json) { _result = result; } public override void OnActionExecuting(ActionExecutingContext context) { if (!context.ModelState.IsValid) { if (_result == ValidationResult.Json) { context.Result = new ValidationFailedResult(context.ModelState); } else { context.Result = ((Controller)context.Controller).View( context.ActionArguments.Values.First()); ValidationFailedResult.SetStatusCodeAndHeaders( context.HttpContext); } } } }
サーバー応答コードと追加情報を追加します
stackoverflowでは、「検証が失敗したときに返すコード」という質問が議論されました。 ファミリー4 **が最適です。 422-すぐに使えるRuby。 ASP.NET MVCは、このテーマに関するベストプラクティスを提供していません。 Rubyと連携しない理由はありません。
internal class ValidationFailedResult: JsonResult { public ValidationFailedResult(ModelStateDictionary modelState) : base(modelState.Select(x => new { x.Key, ValidationState = x.Value.ValidationState.ToString(), x.Value.Errors }).ToList()) { } public override void ExecuteResult(ActionContext context) { base.ExecuteResult(context); SetStatusCodeAndHeaders(context.HttpContext); } internal static void SetStatusCodeAndHeaders(HttpContext context) { context.Response.StatusCode = 422; context.Response.Headers.Add("X-Status-Reason", "Validation failed"); } }
属性を使用
ValidationFilterAttribute
は次で使用できます
- コントローラー方式
- コントローラー
- 世界的に
Json
から
View
を返すコントローラーを分離するだけ
Json
。 これは、2つの基本クラスを作成するか、たとえば、コントローラーの名前空間に
apiが存在するかどうかを確認するなど、属性に合意を追加することで実現できます。
ASP.NET MVCコアのコード例が提供されています。 ASP.NET MVCの場合、 Mvc
名前空間とHttp
名前空間にそれぞれ2組の属性を作成する必要があります。