如何使ViewModel验证与模型验证保持同步?

时间:2014-07-02 00:10:35

标签: c# asp.net-mvc validation ef-code-first asp.net-mvc-5

我正在使用Entity Framework Code First方法,这意味着我的Model需要数据注释属性来创建数据库。我确实希望验证在我的模型上。

我的网站上有一些可以发布一些信息的观点。但是这些信息并不是整个模型,如果我要验证它,验证就会失败。

例如,我可以拥有一个包含这些必需属性的模型:TitleTextX ...但是我可以看到只会发布Text的值。为此,我正在创建一个ViewModel(它还有其他未附加到模型的元素)。但是在这种情况下我如何验证Text?我需要它与模型属性Text进行相同的验证。

有没有办法在Model和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一次只能验证一件事,所以如果我的模型上有多个验证属性,它将无法正常工作。而且我不确定它是否适用于客户端,我甚至没有测试它......

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

虽然您当然可以编写解决方案,但您可能会编写大量代码以避免编写极少量的代码。

有些事情需要考虑。首先,EF和MVC之间的某些验证并不相同。例如,EF使用MaxLength和MinLength,而MVC使用StringLength。

其次,您如何确定您真正想要和不想要的属性?

最后,实际上只有一个属性可以映射到...和所需的属性之间。如果您要使用某个属性进行复制......那么,您刚刚创建了尽可能多的代码PLUS编写了所有代码来进行映射......

我只是采取微小的打击并在两个地方复制映射......