DataValidation Model / ViewModel / Entity Framework Code First

时间:2012-06-01 07:06:02

标签: c# entity-framework code-first asp.net-mvc-4

我正在设计一个包含ASP.NET MVC 4(Beta),VS 11(Beta),EF 5(Beta)的新网站,但这个问题适用于ASP.NET MVC 3,VS 2010,EF的发布版本4,也是。

第一步:我正在使用Entity Framework Code First方法,例如,我有以下用户模型:

public class User
{
  [Key]
  public int UserId {get;set;}

  public String LoginName { get; set; }

  public String Password { get; set; }
}

现在,为了注册我需要另一个模型,即注册模型:

public class Registration
{
  public String LoginName { get; set; }

  public String Password { get; set; }

  public String PasswordConfirm { get; set; }
}

这是我的问题开始的地方:我应该在哪里放置我的DataValidation注释?例如,密码长度至少为10个字符,PasswordConfirmed必须与密码匹配,依此类推。我是否必须在每个可以使用密码做某事的模型上写这个(我正在考虑使用ChangePassword模型)

另一件事是如何处理控制器。当我显示我的注册ViewModel并且一切正常时,我是否创建用户模型并将注册ViewModel中的变量分配给它?

有时我会有很多属性进入数据库,但没有向用户显示(外键,计算值等)。

作为DRY的思考,我不想重复我的自我。

这个的最佳做法是什么?

要明确:注释不是必需的。如果有更好的验证方法,我很高兴,如果你展示它们。

2 个答案:

答案 0 :(得分:2)

我不能客观地说哪个是“最佳做法”,但这就是我看到它的方式。 如果您绑定到视图模型,请验证视图模型,以便:

public class Registration
{

    public String LoginName { get; set; }

    [Required]
    [StringLength(50, MinimumLength=10)]
    public String Password { get; set; }

    [Required]
    [StringLength(50, MinimumLength=10)]
    public String PasswordConfirm { get; set; }
}

您可以在控制器中“手动”进行验证,如果密码和确认匹配则检查POST,如果没有向ModelState添加条目(但可能导致代码重复,并且是有点麻烦)或者在模型上使用漂亮的IValidatableObject接口:

public class Registration : IValidatableObject
{

    public String LoginName { get; set; }

    [Required]
    [StringLength(50, MinimumLength=10)]
    public String Password { get; set; }

    [Required]
    [StringLength(50, MinimumLength=10)]
    public String PasswordConfirm { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext context)
    {
        if(Password != PasswordConfirm)
            yield return new ValidationResult("Confirmation doesn't match", new[] {"PasswordConfirm"})
        //etc.
    }
}

现在,当您在POST之后绑定模型时,只需调用ModelState.IsValid即可完成验证,如果它无效,则会返回错误列表 - 包括您的错误自定义错误。

现在当然你可以将DataAnnotations放在DB模型上作为一个额外的措施,只是为了“以防万一”,以避免字符串截断异常等,如果你以某种方式忘记并试图将更长的字符串推送到数据库< / p>

对于映射,是的,在验证模型后,在POST操作结束时,通常将属性从模型映射到新的User实例(添加时)到DB)或现有的更新。您可以使用AutoMapper或使用反射自己编写一个天真的映射器 - 这是一个相对容易的任务,但最好将其作为一个独立的练习,重新发明轮子是没有意义的。

答案 1 :(得分:1)

您应该只在域图层中创建实体。但是当您需要为您的实体添加一些DataValidation Annotations时,可以使用MvcExtensions。如果您有一些复合或嵌套实体,并且希望将它们作为展平对象,则应使用automapper。这对您来说是最好的做法!