當你有大項目RIA可能不是一個好主意,例如具有不同層次(服務,應用程序,域,基礎結構)的應用程序。
前段時間我不得不在Silverlight應用程序中使用複雜的規則實現驗證。我使用的是使用實體框架生成的自我跟蹤實體。我的一個需要是重新調整所有的驗證代碼。
首先,我嘗試使用EntLib驗證塊並在客戶端和服務器上使用相同的代碼。這種方法不起作用,因爲SL和.NET4.0使用不同版本的DataAnnotations程序集時會遇到一些問題。
最後我最終在服務器上寫了一些驗證服務,返回實體的錯誤(如果有的話)。事情是這樣的:
interface IValidate
{
IEnumerable<string> Validate(Entity entity);
}
,然後在客戶端做的ViewModels實施INotifyDataErrorInfo(此接口支持異步驗證),這樣你就可以驗證與服務的實體,並保存在視圖模型的誤差。
class SomeViewModel : INotifyDataErrorInfo
{
public Entity Entity { get; set; }
public void Validate()
{
this.ClearErrors();
// this method make the service calls
var service = -- service instance --;
var errors = -- get errors from service --;
foreach (string error in errors)
this.AddTopLevelError(error);
}
{...}
}
這樣,所有的驗證邏輯位於服務器上,它可以隨時被添加到一個數據庫之前更改而不影響客戶端,因爲所有的實體througth該服務通過(如果你使用一)。
該服務還可以返回與錯誤相關的錯誤和屬性,這樣您可以與Silverlight進行更豐富的交互。因此,該服務可以是:
interface IValidate
{
IEnumerable<PropertyError> Validate(Entity entity);
}
class PropertyError
{
public string PropertyName { get; }
public IEnumerable<string> Errors { get; }
}
在這裏,你可以看到,驗證規則可以在服務器上的改變,也無所謂這個邏輯是如何實現的。所有這些工作正常並滿足您的請求,問題是Silverlight要求被驗證的對象包含所有帶有錯誤的屬性。
使用數據庫時,這是不是一個常見的情況,因爲你可以有例如(這是一個簡單的模型)
這種模式進行使用實體框架4.1
因爲如果你有一個用戶實例並且想要訪問Email屬性,你必須輸入:user_instance.Person.Email。因此,Email屬性不在用戶類型中,並且這裏是此解決方案的問題,因爲您可能也想驗證EMails。
這是不是這樣,當你有一個實體(像上面)的ViewModel(實現INotifyDataErrorInfo),並希望實體(在這種情況下,用戶)進行驗證,你只需要添加一個錯誤物業Entity.Person.Email。
但世界是不完美的,所以我找到了解決辦法是複製的屬性中的每一個對視圖模型進行驗證,這樣的事:
class SomeViewModel : INotifyDataErrorInfo
{
public User Entity { get; set; }
public string Name { get { return Entity.UserName; } set {...} }
public string Email { get { return Entity.Person.Email; } set {...} }
{...}
}
這樣你就可以綁定控件到ViewModels屬性而不是實體屬性,但它有點難以處理更改通知。
您可能還想檢查:this工具包。它解決了爲您的實體定義wapper的這個問題,並且使用DynamicObject
模擬了一個包含所有包裝屬性的對象。當處理大量數據時,這有點慢,但是很大程度上簡化了工作。
希望這會有所幫助。
Silverlight的重點在於提供一個豐富的客戶端。這通常意味着客戶端的第一級驗證(除了服務器上的任何驗證外)。 RIA服務允許共享自定義驗證器(在客戶端和服務器上運行),但是您的數據模型可能太複雜而無法使用RIA。 –
@HiTech Magic,RIA絕對不在。我已經有一個類庫和一個Silverlight類庫共享課程。我使用啓用Silverlight的WCF服務將數據從服務器發送到客戶端。我確實有一些客戶端驗證,但這還不夠。該圖必須返回到服務器進行完整驗證。 –
如果您的驗證代碼可以用於客戶端和服務器,那麼您可以使用RIA服務項目的* .shared.cs *功能來保存跨項目的文件鏈接。沒有太多的幫助,但比添加鏈接更整潔。 –