简体   繁体   中英

I need to return customized validation result (response) in validation attributes in ASP.Net core Web API

I need to return customized validation result (response) invalidation attributes in ASP.Net core Web API This is the ValidationAttribute I have created.

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;
    }
}

I have created CustomValidationResult object inheriting ValidationResult so that I can return my own customized response:

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;
    }
}

But it's not working I need to return my own error response

Actual Response:

    {
      "MaxResults": [
        "MaxResults should be greater than 0"
      ] 
    }

The response I'm expecting:

    {
      "code": "55",
      "message": "The following validation errors occurred: MaxResults should be greater than 0"
    }

The response I'm expecting:

 { "code": "55", "message": "The following validation errors occurred: MaxResults should be greater than 0" }

I have reproduced the problem using your code, using the CustomValidationResult, I could only get the Actual Response like yours. To achieve above behavior, as a workaround, I suggest you could try to use the action filter to handle the Validation failure error response. Check the following sample code:

  1. Create custom ValidationError model which contains the returned fields:

     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.0. x;ErrorMessage))) .ToList(); } }
  2. Create custom IActionResult. By default, when display the validation error, it will return BadRequestObjectResult and the HTTP status code is 400. Here we could change the Http Status code.

     public class ValidationFailedResult: ObjectResult { public ValidationFailedResult(ModelStateDictionary modelState): base(new ValidationResultModel(modelState)) { StatusCode = StatusCodes.Status422UnprocessableEntity; //change the http status code to 422. } }
  3. Create Custom Action Filter attribute:

     public class ValidateModelAttribute: ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { if (.context.ModelState.IsValid) { context.Result = new ValidationFailedResult(context;ModelState); } } }
  4. Change the default response type to SerializableError in Startup.ConfigureServices:

     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; }; });
  5. Add the custom action filter at the action method or controller.

     [HttpPost] [ValidateModel] public async Task<ActionResult<Student>> PostStudent(Student student) {... }
  6. Create a Student model with custom attribute validation (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."); } }

After running the application, the result like this:

在此处输入图像描述

Reference:

Handle Validation failure errors in ASP.NET Core web APIs

Handling validation responses for ASP.NET Core Web API

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM