[HttpPost] public IActionResult Test(SomeParam param) { if (!ModelState.IsValid) { return View(param); // return Json({success: false, state: ModelState}); } dbContext.UpdateData(param); return RedirectToAction("index"); // return Ok({success: true}); }
このコードは改善できます:
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組の属性を作成する必要があります。