:
在講MVC的token的時候,我簡單的說了一下如果用LINQ生成實體的話如何做業務邏輯驗證。現在我來詳細說一下:
[Column(Storage="_userMail", DbType="VarChar(100)")]
public string userMail
{
get
{
return this._userMail;
}
set
{
if ((this._userMail != value))
{
this.OnuserMailChanging(value);
this.SendPropertyChanging();
this._userMail = value;
this.SendPropertyChanged("userMail");
this.OnuserMailChanged ();
}
}
}
上面代碼是dbml的designer類,是由LINQ自動生成的代碼,從代碼中可以看到LINQ為userMail的字段生成了get,set方法,留意一下set方法裡面,首先調用了 this.OnuserMailChanging(value)的方法,也就是說我們可以在這個方法裡面做一些業務邏輯的判斷,如:
partial void OnuserMailChanging(string value)
{
Regex reg = new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.] \w+)*");
if (!reg.IsMatch(value))
{
throw new ArgumentException("format error!");
}
}
我在OnuserMailChanging方法中去判斷傳入的Value是否是郵件格式,這個方法會在實體賦值的時候(set)的時候就調用,如果格式錯誤,則報錯,不再進行賦值,如果 我們試圖在Changing方法中就對value進行過濾HTML字符的操作,那麼實際上是無效的,首先是形參跟實參的關系,改了value的值實際上不會更改到實參的值,其次如果在 Changing方法裡面就更改_userMail字段的值,如下所示:
partial void OnuserMailChanging(string value)
{
_userMail = FilterContent(_userMail);
}
在Changing事件中過濾並且賦值給字段,這麼改實際上是可行的,但是留意下desinger類裡面的set處理中當調用完Changing事件之後又會把value值重新賦給字段,那麼 之前Changing事件裡面所做的賦值操作實際上是沒有意義的。有人說可以把後面的賦值代碼去掉,實際上desinger類不主張修改,因為該類是自動生成的,你所做的修改實 際上下次更改layout的時候又會被覆蓋掉了。最好的做法是把過濾放到Changed事件裡面,留意下set處理中Changed事件是在賦值後,所以在裡面更改字段的值是有意義的, 如:
partial void OnuserMailChanged()
{
_userMail = FilterContent(_userMail);
}
這樣把Changing與Changed相結合,在實體中即做格式驗證,又做腳本過濾,才能使實體更加健壯!