如何使ViewModel的验证与Model的验证保持同步?

4
我正在使用Entity Framework Code First方法,这意味着我的模型需要数据注释属性来创建数据库。我希望验证在我的模型上进行。
我的网站上有一些视图可以发布一些信息。但是这个信息并不是整个模型,如果我要验证它,验证会失败。
例如,我可能有一个具有这些“required”属性的模型:TitleTextX...但是我可能有一个视图只会发布Text的值。为此,我创建了一个ViewModel(其中还有其他未附加到模型的元素)。但是,在这种情况下,如何验证Text?我需要它与模型属性Text具有相同的验证。
有没有办法在模型和ViewModel上拥有相同的验证而不重复代码?
这是一个根本行不通的尝试...
我想创建一个自定义属性,将验证链接到模型:
/* This wouldn't work */
public class PropertyValidationAttribute : ValidationAttribute
{
    public Type Type { get; set; }

    public string PropertyName { get; set; }

    public PropertyValidationAttribute(Type type, string propertyName)
    {
        Type = type;
        PropertyName = propertyName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var attrs = Type.GetProperty(PropertyName).GetCustomAttributes(typeof(ValidationAttribute), true) as IEnumerable<ValidationAttribute>;

        if (attrs != null)
        {
            foreach (var attr in attrs)
            {
                return attr.GetValidationResult(value, validationContext);
            }
        }

        return base.IsValid(value, validationContext);
    }
}

以上所述的问题在于每个ValidationAttribute一次只能验证一件事情,因此如果我在我的模型上有多个验证属性,它将无法正常工作。而且我不确定它是否适用于客户端,我甚至没有测试过...


我一定漏掉了什么。你说:“但是在这种情况下,我该如何验证文本?我需要它具有与模型属性Text相同的验证”。你需要在视图模型中复制哪些模型上的验证呢? - Justin Helgerson
我需要在ViewModel中使用它才能使用客户端验证... - BrunoLM
1
你能否将属性应用于模型和视图模型两者之间?或者这就是你试图避免的重复吗? - Rowan Freeman
2个回答

0

在将模型映射到视图模型时,您可以使用反射来检查任何验证属性,然后将这些相同的属性应用于您的视图模型。假设您的模型和视图模型上的属性名称相同,那么您将能够创建一个方法来执行此操作。


0

虽然你肯定可以想出一个解决方案,但为了避免编写非常少量的代码而编写大量的代码,你可能需要考虑一些事情。

首先,EF和MVC之间某些验证不同。例如,EF使用MaxLength和MinLength,而MVC使用StringLength。

其次,你要如何确定哪些属性实际上是你想要的,哪些不是?

最后,只有一个属性在映射之间进行映射,那就是必需的。如果你要使用一个属性来复制...好吧,你刚刚创建了同样多的代码,还编写了所有映射的代码...

我会接受这个小问题,并在两个地方都复制映射...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接