c# - DataValidation 模型/ViewModel/ Entity Framework 代码优先

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

我正在使用 ASP.NET MVC 4(测试版)、VS 11(测试版)、EF 5(测试版)设计一个新网站,但这个问题适用于 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 必须与 Password 相匹配,等等。我是否必须在每个可以用密码做某事的模型上写这个(我也在考虑有一个 ChangePassword 模型)

另一件事是如何与 Controller 打交道。当我显示我的 Registration ViewModel 并且一切正常时,我是否创建了一个 User 模型并将 Registration ViewModel 中的变量分配给它?

有时我有很多属性会转到数据库,但不会向用户显示(外键、计算值等)。

作为 DRY 的 thinkink,我不想重复我自己。

这方面的最佳实践是什么?

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

最佳答案

我不能客观地说哪个是“最佳实践”,但这是我的看法。 如果您要绑定(bind)到 View 模型,请验证 View 模型,因此:

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; }
}

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

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 之后绑定(bind)模型时,只需调用 ModelState.IsValid 即可完成验证,如果无效,则返回错误列表 - 包括您的自定义错误。

当然,现在您也可以将 DataAnnotations 作为附加措施放在 DB 模型上,只是为了“以防万一”避免字符串截断异常等,如果您不知何故忘记并尝试将更长的字符串推送到数据库

至于映射,是的,在验证模型之后,在 POST 操作结束时,您通常会将模型中的属性映射到新的 User 实例(添加到数据库时)或现有实例进行更新。您可以使用 AutoMapper或使用反射自己编写一个简单的映射器 - 这是一项相对容易的任务,但最好将其作为一个独立的练习,因为没有必要重新发明轮子。

关于c# - DataValidation 模型/ViewModel/ Entity Framework 代码优先,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10845876/

相关文章:

c# - EF Core 2.0 Code First 查询错误 (DetachedLazyLoadingWarning)

c# - 字符串删除html

c# - 检索 SQL Server 表中特定范围的行

entity-framework - Entity Framework 迁移 - 如何创建单元测试以确保迁移模型是最新的?

c# - AspNetUsers' ID 作为单独表中的外键,一对一关系

Oracle.ManagedDataAccess.EntityFramework-ORA-01918 : user 'dbo' does not exist

c# - SingleProducerConstrained 和 MaxDegreeOfParallelism

c# - 为什么将 OrderBy 添加到 LINQ to EF 查询可以提高其性能?

entity-framework - 如何从 psake 构建运行代码优先迁移?

entity-framework - 在 EF Code First 中启用级联删除而不暴露外键