只是一個問題,如果我使用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