Как предотвратить проверку свойства модели в контроллере mvc в AspNet Core? - PullRequest
0 голосов
/ 25 мая 2018

У меня есть действие контроллера MVC, которое получает сложный тип с некоторыми списками сотрудников.В моем пользовательском модуле связывания я разделяю сотрудников на принятых и отклоненных и возвращаю ExcelEmployeeModel

public class ExcelEmployeeModel
{
    [Required] public String Description { get; set; }
    public List<Employee> Accepted { get; set; }
    public List<Employee> RejectedEmployees { get; set; }
}

public class Employee
{
    public Int32 Id { get; set; }
    [Required] public string FirstName { get; set; }
    [Required] public string LastName { get; set; }
}

. Кажется, AspNetCore вызывает validate для каждого из сотрудников в списке и отправляет объект BadRequest обратно клиенту.если есть отклоненные сотрудники.Поэтому, если есть отклоненные сотрудники, действие никогда не выполняется.

Как предотвратить проверку свойства, такого как RejectedEmployees?

Было бы неплохо просто украсить мое свойство с помощью пользовательского атрибута следующим образом:

[NoValidation]
public List<Employee> RejectedEmployees {get;set;}

Этот атрибут ValidationAttribute является причиной для проверки элементов работника, и оттуда возвращается неверный запрос.

// Conifguration file StartUp.cs
services.AddMvc(options =>
{
    options.Filters.Add(new ValidateModelAttribute());
}

// Custom validation attribute class
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }
}

Это действие, которое должно получать данные, но не получает их.

[HttpPost]
public async Task<IActionResult> Post([FromBody] ExcelEmployeeModel model)
{
 ... 
}

1 Ответ

0 голосов
/ 25 мая 2018

Следующее, вероятно, будет моим окончательным решением.

public class NoValidationAttribute : ValidationAttribute
{
    public static void RemoveValidation(ActionExecutingContext context)
    {
        // Get the properties that contain the [NoValidationAttribute]
        var properties = context.ActionArguments.First().Value.GetType()
            .GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(a =>
                a.GetCustomAttributes(true).OfType<NoValidationAttribute>().Any());

        // For each of the properties remove the modelstate errors.
        foreach (var property in properties)
        {
            foreach (var key in context.ModelState.Keys.Where(k =>
                k.StartsWith($"{property.Name}["))) // Item index is part of key [
            {
                context.ModelState.Remove(key);
            }
        }
    }
}

И мой атрибут ValidationModelAttribute теперь выглядит следующим образом:

public override void OnActionExecuting(ActionExecutingContext context)
{
    NoValidationAttribute.RemoveValidation(context);

    // Finally validation passes for properties using the [NoValidateAttribute]
    if (!context.ModelState.IsValid)
    {
        context.Result = new BadRequestObjectResult(context.ModelState);
    }
}

// Model using the NoValidationAttribute
public class ExcelEmployeeModel
{
    [Required] public String Description { get; set; }
    public List<Employee> Accepted { get; set; }
    [NoValidation]
    public List<Employee> RejectedEmployees { get; set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...