使用EntityFramwork和ASPNET中的注释验证修改后的模型

时间:2016-12-10 11:31:04

标签: asp.net entity-framework validation model

我将此课程作为EF模型的一部分:

class Person {
    public int Id { get; set; }

    [MaxLength(100, ErrorMessage="Name cannot be more than 100 characters")]
    public string Name { get; set; }
}

我在控制器中有这个方法:

public IActionResult ChangeName(int id, string name) {
    var person = db.Persons.Find(id);
    if(person == null) return NotFound();
    person.Name = name;
    db.SaveChanges();
    return Json(new {result = "Saved Successfully"});
}

有没有办法在使用注释person更改Name属性后验证MaxLength,而不是手动检查它。有时我可能会有多个验证,而我不想检查每一个。此外,我可能会在将来更改这些参数(例如,使最大长度为200),这意味着我必须在其他地方更改它。

有可能吗?

2 个答案:

答案 0 :(得分:0)

好的,我找到了解决问题的方法,我创建了一个获取模型并检查错误的方法:

private IDictionary<string, string> ValidateModel(Person model)
{
    var errors = new Dictionary<string, string>();
    foreach (var property in model.GetType().GetProperties())
    {
        foreach (var attribute in property.GetCustomAttributes())
        {
            var validationAttribute = attribute as ValidationAttribute;
            if(validationAttribute == null) continue;
            var value = property.GetValue(model);
            if (!validationAttribute.IsValid(value))
            {
                errors.Add(property.Name, validationAttribute.ErrorMessage);
            }
        }
    }
    return errors;
}

<强>更新

正如@Gert Arnold所述,上述方法每个属性只返回一次验证。下面是修复版本,它返回每个属性的错误列表

public static IDictionary<string, IList<string>> ValidateModel(Person model)
{
    var errors = new Dictionary<string, IList<string>>();
    foreach (var property in model.GetType().GetProperties())
    {
        foreach (var attribute in property.GetCustomAttributes())
        {
            var validationAttribute = attribute as ValidationAttribute;
            if (validationAttribute == null) continue;
            var value = property.GetValue(model);
            if (validationAttribute.IsValid(value)) continue;
            if (!errors.ContainsKey(property.Name))
                errors[property.Name] = new List<string>();
            errors[property.Name].Add(validationAttribute.ErrorMessage);
        }
    }
    return errors;
}

答案 1 :(得分:0)

只要每个属性有一个验证错误,您的方法就可以正常工作。而且,它非常复杂。您可以使用db.GetValidationErrors()获得相同的结果。一个区别是每个属性名称在集合中收集错误:

var errors = db.GetValidationErrors()
               .SelectMany(devr => devr.ValidationErrors)
               .GroupBy(ve => ve.PropertyName)
               .ToDictionary(ve => ve.Key, ve => ve.Select(v => v.ErrorMessage));