using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc;
namespace DotNetCoreApiSample.Controllers { [Route("api/[controller]")] public class ValidationDemoController : Controller { [HttpPost] public IActionResult AddUser([FromBody]User user) { string errorMessage = string.Empty; if (!ModelState.IsValid) { foreach (var item in ModelState.Values) { foreach (var error in item.Errors) { errorMessage += error.ErrorMessage + "|"; } } } if(!string.IsNullOrEmpty(errorMessage)) { return BadRequest(errorMessage); } return Ok(); } }
public class User { [Required(ErrorMessage = "用户Code不能为空")] public string Code { get; set; } [Required(ErrorMessage = "用户名称不能为空")] public string Name { get; set; } [Required(ErrorMessage = "用户年龄不能为空")] [Range(1, 100, ErrorMessage = "年龄必须介于1~100之间")] public int Age { get; set; } public string Address { get; set; } } }
namespace DotNetCoreApiSample.Filters { public class ValidateModelAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { if (!context.ModelState.IsValid) { var result = context.ModelState.Keys .SelectMany(key => context.ModelState[key].Errors.Select(x => new ValidationError(key, x.ErrorMessage))) .ToList(); context.Result = new ObjectResult(result); } } } public class ValidationError { [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string Field { get; } public string Message { get; } public ValidationError(string field, string message) { Field = field != string.Empty ? field : null; Message = message; } } }
public class ApiResultFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { base.OnActionExecuting(context); } public override void OnResultExecuting(ResultExecutingContext context) { var objectResult = context.Result as ObjectResult; context.Result = new OkObjectResult(new BaseResultModel(code:200, result: objectResult.Value)); } }
public class ValidationFailedResultModel : BaseResultModel { public ValidationFailedResultModel(ModelStateDictionary modelState) { Code = 422; Message = "参数不合法"; Result = modelState.Keys .SelectMany(key => modelState[key].Errors.Select(x => new ValidationError(key, x.ErrorMessage))) .ToList(); ReturnStatus = ReturnStatus.Fail; } }
public class ValidationError { [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string Field { get; } public string Message { get; } public ValidationError(string field, string message) { Field = field != string.Empty ? field : null; Message = message; } }
public override void OnActionExecuting(ActionExecutingContext context) { if (!context.ModelState.IsValid) { context.Result = new ValidationFailedResult(context.ModelState); } }
public override void OnResultExecuting(ResultExecutingContext context) { if (context.Result is ValidationFailedResult) { var objectResult = context.Result as ObjectResult; context.Result = objectResult; } else { var objectResult = context.Result as ObjectResult; context.Result = new OkObjectResult(new BaseResultModel(code: 200, result: objectResult.Value)); } }
4、调用参数验证接口结果如下
异常处理
异常处理和参数验证的方式基本相同,有以下几个步骤
1、创建名为 CustomExceptionResultModel 的模型类
1 2 3 4 5 6 7 8 9 10 11 12
public class CustomExceptionResultModel:BaseResultModel { public CustomExceptionResultModel(int? code, Exception exception) { Code = code; Message = exception.InnerException != null ? exception.InnerException.Message : exception.Message; Result = exception.Message; ReturnStatus = ReturnStatus.Error; } }
2、创建名为 CustomExceptionResult 的异常结果类
1 2 3 4 5 6 7 8
public class CustomExceptionResult:ObjectResult { public CustomExceptionResult(int? code, Exception exception) : base(new CustomExceptionResultModel(code, exception)) { StatusCode = code; } }
public class CustomExceptionAttribute : IExceptionFilter { public void OnException(ExceptionContext context) { HttpStatusCode status = HttpStatusCode.InternalServerError;
//处理各种异常
context.ExceptionHandled = true; context.Result = new CustomExceptionResult((int)status, context.Exception); } }