问题描述
我需要在ASP.Net核心Web API中返回自定义的验证结果(响应)无效属性 这是我创建的ValidationAttribute。
class MaxResultsAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value,ValidationContext validationContext)
{
int maxResults = (int)value;
if (maxResults <= 0)
{
return new CustomValidationResult(new ValidationResult("MaxResults should be greater than 0"));
}
return ValidationResult.Success;
}
}
我创建了继承ValidationResult的CustomValidationResult对象,以便可以返回自己的自定义响应:
public class CustomValidationResult : ValidationResult
{
public int FaultCode { get; set; }
public string FaultMessage { get; set; }
public CustomValidationResult(ValidationResult validationResult) : base(validationResult)
{
FaultCode = 123;
FaultMessage = validationResult.ErrorMessage;
}
}
但是它不起作用 我需要返回自己的错误响应
实际反应:
{
"MaxResults": [
"MaxResults should be greater than 0"
]
}
期望得到的答复:
{
"code": "55","message": "The following validation errors occurred: MaxResults should be greater than 0"
}
解决方法
期望得到的答复:
{ "code": "55","message": "The following validation errors occurred: MaxResults should be greater than 0" }
我已经使用您的代码通过CustomValidationResult重现了该问题,我只能像您一样获得实际响应。为了解决上述问题,作为一种解决方法,建议您尝试使用操作过滤器来处理“验证失败”错误响应。检查以下示例代码:
-
创建包含返回字段的自定义ValidationError模型:
public class ValidationError { [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string Field { get; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public int Code { get; set; } public string Message { get; } public ValidationError(string field,int code,string message) { Field = field != string.Empty ? field : null; Code = code != 0 ? code : 55; Message = message; } } public class ValidationResultModel { public string Message { get; } public List<ValidationError> Errors { get; } public ValidationResultModel(ModelStateDictionary modelState) { Message = "Validation Failed"; Errors = modelState.Keys .SelectMany(key => modelState[key].Errors.Select(x => new ValidationError(key,x.ErrorMessage))) .ToList(); } }
-
创建自定义IActionResult。默认情况下,显示验证错误时,它将返回BadRequestObjectResult,并且HTTP状态代码为400。在这里,我们可以更改Http状态代码。
public class ValidationFailedResult : ObjectResult { public ValidationFailedResult(ModelStateDictionary modelState) : base(new ValidationResultModel(modelState)) { StatusCode = StatusCodes.Status422UnprocessableEntity; //change the http status code to 422. } }
-
创建自定义操作过滤器属性:
public class ValidateModelAttribute: ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { if (!context.ModelState.IsValid) { context.Result = new ValidationFailedResult(context.ModelState); } } }
-
在Startup.ConfigureServices中将默认响应类型更改为SerializableError:
services.AddControllers().ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { var result = new ValidationFailedResult(context.ModelState); // TODO: add `using System.Net.Mime;` to resolve MediaTypeNames result.ContentTypes.Add(MediaTypeNames.Application.Json); result.ContentTypes.Add(MediaTypeNames.Application.Xml); return result; }; });
-
在操作方法或控制器上添加自定义操作过滤器。
[HttpPost] [ValidateModel] public async Task<ActionResult<Student>> PostStudent(Student student) { ... }
-
使用自定义属性验证(Min18Years)创建学生模型:
public class Student { [Key] public int Id { get; set; } [Required(ErrorMessage = "Please enter name")] public string Name { get; set; } [Required(ErrorMessage = "Please choose admission date.")] [Display(Name = "Admission Date")] [DataType(DataType.Date)] public DateTime AdmissionDate { get; set; } [Display(Name = "Date of Birth")] [DataType(DataType.Date)] [Min18Years] public DateTime DateofBirth { get; set; } } public class Min18Years : ValidationAttribute { protected override ValidationResult IsValid(object value,ValidationContext validationContext) { var student = (Student)validationContext.ObjectInstance; if (student.DateofBirth == null) return new ValidationResult("Date of Birth is required."); var age = DateTime.Today.Year - student.DateofBirth.Year; if (age <= 0) { return new ValidationResult("MaxResults should be greater than 0"); } return (age >= 18) ? ValidationResult.Success : new ValidationResult("Student should be at least 18 years old."); } }
运行应用程序后,结果如下:
参考: