只是一个问题,如果我使用asp.net mvc作为我的ddd应用程序的前端,那么如果我想验证我的域实体,我可以使用asp.net mvc验证属性吗?域验证问题
因为我认为我们的域不应该绑定到任何特定的编程语言,所以使用mvc验证属性是尴尬的。
如果我使用mvc验证属性,它将帮助我有效地进行验证,而不是写入自定义。
请帮我选择一个正确的方法。
只是一个问题,如果我使用asp.net mvc作为我的ddd应用程序的前端,那么如果我想验证我的域实体,我可以使用asp.net mvc验证属性吗?域验证问题
因为我认为我们的域不应该绑定到任何特定的编程语言,所以使用mvc验证属性是尴尬的。
如果我使用mvc验证属性,它将帮助我有效地进行验证,而不是写入自定义。
请帮我选择一个正确的方法。
您可以在视图模型上使用验证属性,但不能在域模型上使用验证属性。
我已经写了为什么在另一个答案(我知道你已经找到了,但其他人可能有兴趣):https://stackoverflow.com/a/9765945/70386
大多数映射器(如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。它是一个单独的组件。
感谢您的宝贵答案,我还有一个问题,假设我需要验证喜欢看看给定的电子邮件是否已经在数据库中存在注册之前,如果是,那么不要给出错误信息,否则坚持它,我在哪里把这种类型的验证检查数据库像重复,电子邮件之前坚持它。 – kamal 2012-03-28 18:54:00
该验证逻辑不能由域类本身执行,因为它没有且不应该有权访问电子邮件地址的存储库。相反,验证应放置在协调域中操作的服务中。该服务将引用通过ID加载域实体的存储库,以及可验证电子邮件地址唯一性的存储库。这个服务可以被MVC控制器引用。服务抽象并非绝对必要,您可以将所有编排代码直接放置在控制器中。 – eulerfx 2012-03-28 19:20:09
你的意思是在域服务中加入验证并注入库吗?你能提供一些代码或其他网站的任何一行吗?这对我的理解会很有帮助。 – kamal 2012-03-29 11:33:48
同意,但取决于应用程序的大小和规模,他可能会选择将他的技术栈集成到他的域中。这不会是_purest_DDD解决方案,但可能更适合他(尽管我完全同意你的答案)。 – 2012-03-27 13:58:43
@jqauffin \t 感谢您宝贵的回答,我还有一个问题,假设我需要验证,以便在注册之前查看给定的电子邮件是否已经存在于数据库中,如果是,则不要给出错误消息或者坚持它,在哪里我把这种类型的数据库检查类似重复,电子邮件之前坚持它 – kamal 2012-03-28 18:54:31