ASP.NET RC2 - ModelState不验证集合的元素

时间:2016-07-21 12:58:22

标签: asp.net validation asp.net-core modelstate

让我们说我的上面有必需属性的简单模型。

public class User
{
    [Required]
    string Name {get;set;}
    string Surname {get;set;}
}

当我POST / PUT只有一个User和Name的实例为空时,它运行得很好。 ModelState无效且包含错误。

当我POST / PUT对象集合时,用户和其中一些名称为空,则ModelState有效且不包含任何验证错误。

你能告诉我它有什么问题吗?它为什么只关注收藏品?当我有一个关系为one-many的对象时,我注意到了同样的行为。然后,ModelState中的此集合中的集合也未经过验证。

我不想手动验证必填字段,它应该自动生效。

1 个答案:

答案 0 :(得分:-1)

您需要创建一个ActionFilter

public class ModelStateValidActionFilter : IAsyncActionFilter
{
    public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        // Validate ICollection
        if (context.ActionArguments.Count == 1 && context.ActionArguments.First().Value.GetType().IsListType())
        {
            foreach (var arg in (IList)context.ActionArguments.First().Value  )
            {
                var parameters = arg.GetType().GetProperties();
                foreach (var parameter in parameters)
                {
                    var argument = context.ActionArguments.GetOrDefault(parameter.Name);
                    EvaluateValidationAttributes(parameter, argument, context.ModelState);
                }
            }
        }

        if (context.ModelState.IsValid)
        {
            return next();
        }
        context.Result = new BadRequestObjectResult(context.ModelState);
        return Task.CompletedTask;
    }

    private void EvaluateValidationAttributes(PropertyInfo parameter, object argument, ModelStateDictionary modelState)
    {
        var validationAttributes = parameter.CustomAttributes;
        foreach (var attributeData in validationAttributes)
        {
            var attributeInstance = parameter.GetCustomAttribute(attributeData.AttributeType);
            var validationAttribute = attributeInstance as ValidationAttribute;
            if (validationAttribute != null)
            {
                var isValid = validationAttribute.IsValid(argument);
                if (!isValid)
                {
                    modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name));
                }
            }
        }
    }

并将其添加到MVC选项中

services.AddMvc()
    .AddMvcOptions(opts =>
    {
        opts.Filters.Add(new ModelStateValidActionFilter());
    }