Asp.net mvc 域验证问题

Asp.net mvc 域验证问题,asp.net-mvc,domain-driven-design,Asp.net Mvc,Domain Driven Design,只是一个问题,如果我使用asp.net mvc作为ddd应用程序的前端,那么如果我希望在域实体中进行验证,我可以使用asp.net mvc验证属性进行验证吗 因为我认为我们的领域不应该绑定到任何特定的编程语言,所以使用mvc验证属性是很尴尬的 如果我使用mvc验证属性,它将帮助我有效地进行验证,而不是编写自定义 请帮助我选择正确的方法。您可以在视图模型上使用验证属性,但不能在域模型上使用 我在另一个答案中写下了原因(我知道你已经找到了,但其他人可能会感兴趣): 大多数映射程序(如Automapp

只是一个问题,如果我使用asp.net mvc作为ddd应用程序的前端,那么如果我希望在域实体中进行验证,我可以使用asp.net mvc验证属性进行验证吗

因为我认为我们的领域不应该绑定到任何特定的编程语言,所以使用mvc验证属性是很尴尬的

如果我使用mvc验证属性,它将帮助我有效地进行验证,而不是编写自定义


请帮助我选择正确的方法。

您可以在视图模型上使用验证属性,但不能在域模型上使用

我在另一个答案中写下了原因(我知道你已经找到了,但其他人可能会感兴趣):

大多数映射程序(如Automapper)在没有公共属性的情况下工作,因此您可以验证视图模型,然后将信息复制到域模型

该解决方案的问题是可能不会触发域事件(以及域模型方法中更复杂的验证逻辑)


域模型迫使您在域之后设计UI(因为CRUD应用程序不能很好地与域模型配合使用)。一开始可能会觉得有点尴尬,但用户体验会更高。

我经常采用的方法是使用
System.ComponentModel.DataAnnotations
属性来验证ASP.NET MVC视图模型DTO,然后让DTO相应地更新或创建域对象。域对象在没有验证属性的情况下验证自己,而是使用常规参数检查抛出
ArgumentException
实例。这允许域对象始终保持一致,就像求助于验证框架一样,在实体被持久化之前,必须小心地执行验证逻辑(通过直接调用或拦截ORM事件)。例如:

// this view model class lives in a Models folder in the ASP.NET MVC project
public class PersonViewModel
{
  [Required]  
  public string Name { get; set; }

  [DataType(DataType.EmailAddress)]
  public string Email { get; set; }

  public Person ToPerson()
  {
    return new Person(this.Name, this.Email);
  }

  public void UpdatePerson(Person person)
  {
    person.Name = this.Name;
    person.Email = this.Email;
  }
}

// this domain class normally lives in the domain layer project
public class Person
{
  public Person(string name, string email = null)
  {
    this.Name = name;
    this.Email = email;
  }

  string name;
  string email;

  public string Name
  {
    get { return this.name; }
    set 
    {
        if (string.IsNullOrEmpty(value)) 
          throw new ArgumentException();
        this.name = value;
    }
  }

  public string Email
  {
    get { return this.email; }
    set 
    {
        if (!string.IsNullOrEmpty(value) && !IsValidEmail(value))
          throw new ArgumentException();        
        this.email = value;
    }
  }
}

此外,您可以选择使用
System.ComponentModel.DataAnnotations
中的验证属性,而无需使用ASP.NET MVC。这是一个单独的组件。

同意,但根据应用程序的大小和规模,他可能会选择将技术堆栈集成到自己的领域中。这不是最纯粹的DDD解决方案,但可能更适合他(尽管我完全同意你的回答)。@jqauffin感谢你宝贵的回答,我还有一个问题,假设我需要验证,看看在注册之前给定的电子邮件是否已经存在于DB中,如果是,则不要给出错误消息或将其持久化,我应该将这种类型的验证放在哪里,例如在持久化之前检查db duplicate,email感谢您宝贵的答案,我还有一个问题,假设我需要验证,以查看在注册之前给定的电子邮件是否已经存在于db中,如果是,则不要给出错误消息或将其持久化,在持久化之前,我应该将这种类型的签入db(如duplicate)电子邮件的验证放在何处。该验证逻辑不能由域类本身执行,因为它没有也不应该访问电子邮件地址存储库。相反,验证应该放在协调域上操作的服务中。该服务将有一个对存储库的引用,该存储库按ID加载域实体,以及一个可以验证电子邮件地址唯一性的存储库。然后,MVC控制器可以引用该服务。服务抽象不是绝对必要的,您可以直接将所有业务流程代码放在控制器中。您的意思是将验证放在域服务中,并将存储库注入其中?你能提供一些代码,或者其他网站的任何一行代码吗。这会对我的理解有很大帮助。