Мне нужно вернуть настроенный результат проверки (ответ) в атрибутах проверки в основном веб-API ASP.Net.

Мне нужно вернуть настроенные атрибуты недействительности результата проверки (ответа) в основном веб-API ASP.Net. Это созданный мной 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;
    }
}

Я создал объект CustomValidationResult, наследующий ValidationResult, чтобы я мог вернуть свой собственный настроенный ответ:

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

person krish    schedule 09.10.2020    source источник
comment
Возможно, это может помочь: docs.microsoft.com /en-us/aspnet/core/web-api/advanced/   -  person vernou    schedule 09.10.2020


Ответы (1)


Ожидаемый ответ:

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

Я воспроизвел проблему, используя ваш код, используя CustomValidationResult, я мог получить только фактический ответ, подобный вашему. Чтобы добиться вышеуказанного поведения, в качестве обходного пути я предлагаю вам попробовать использовать фильтр действий для обработки ответа об ошибке Validation failure. Проверьте следующий пример кода:

  1. Создайте пользовательскую модель 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,0, x.ErrorMessage)))
                     .ToList();
         }
     }
    
  2. Создайте собственный 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.
         }
     }
    
  3. Создайте атрибут пользовательского фильтра действий:

     public class ValidateModelAttribute: ActionFilterAttribute
     { 
         public override void OnActionExecuting(ActionExecutingContext context)
         {
             if (!context.ModelState.IsValid)
             {
                 context.Result = new ValidationFailedResult(context.ModelState);
             }
         }
     }
    
  4. Измените тип ответа по умолчанию на SerializableError в 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. Добавьте настраиваемый фильтр действий в метод действия или контроллер.

     [HttpPost]
     [ValidateModel]
     public async Task<ActionResult<Student>> PostStudent(Student student)
     { 
        ...
     }
    
  6. Создайте модель 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.");
         }
     }  
    

После запуска приложения результат такой:

введите здесь описание изображения

Справка:

Обработка ошибок сбоя проверки в веб-API ASP.NET Core

Обработка ответов проверки для ASP.NET Core Web API

person Zhi Lv    schedule 09.10.2020