我将此课程作为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),这意味着我必须在其他地方更改它。
有可能吗?
答案 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));