2012-04-06 21 views
2

我的Silverlight的解決方案有3個項目文件你如何設置Customvalidation在元數據文件,如果元數據是在不同的型號項目

  1. Silverlight的部分(客戶端)
  2. Web部件(服務器)
  3. 實體模型(我在一個單獨項目中將元數據與元數據一起維護)

元數據文件是一個帶有relavent數據註解驗證的分部類。

[MetadataTypeAttribute(typeof(User.UserMetadata))] 
public partial class User 
{ 
    [CustomValidation(typeof(UsernameValidator), "IsUsernameAvailable")] 
    public string UserName { get; set; } 
} 

現在的問題是,我需要保持這種類UsernameValidator 如果我的元數據類和EDMX都在服務器端(網頁),那麼我知道我需要在我的web項目中創建.shared.cs類,然後添加適當的靜態方法。

我的IsUserAvailable方法實習生將調用一個domainservice方法作爲asyc驗證的一部分。

[Invoke] 
    public bool IsUsernameAvailable(string username) 
    { 
     return !Membership.FindUsersByName(username).Cast<MembershipUser>().Any(); 
    } 

如果我的元數據類是在同一個項目作爲我的域業務處於然後我可以叫從我UsernameValidator.Shared.cs類域服務方法。

但是在這裏,我的實體模型和元數據在單獨的庫中。

任何想法可以理解

傑夫奇妙的解釋這裏的ASYC驗證 http://jeffhandley.com/archive/2010/05/26/asyncvalidation-again.aspx 但是當你的模型,元數據和共享類,都是在服務器端只會工作。

回答

1

有一種破解可以做到這一點。這不是一個乾淨的方式,但它可能會工作。

因爲.shared處理代碼生成,它不會抱怨代碼#if括號中的某些編譯錯誤。所以你可以做的是在任何項目中創建一個Validator.Shared.cs,並確保它生成Silverlight端。

添加以下代碼。並且不要忘記命名空間。

#if SILVERLIGHT 
using WebProject.Web.Services; 
using System.ServiceModel.DomainServices.Client; 
#endif 



#if SILVERLIGHT 
      UserContext context = new UserContext(); 
      InvokeOperation<bool> availability = context.DoesUserExist(username); 
      //code ommited. use what logic you want, maybe Jeffs post. 
#endif 

編譯器將忽略此代碼部分,因爲它不符合if語句的條件。與此同時,在silverlight客戶端,它會嘗試重新編譯共享驗證器,使其符合if語句的條件。

就像我說的。這不是一個乾淨的方式來做到這一點。而且你可能會遇到缺少命名空間的問題。您需要在未生成的Validator.shared.cs中解析它們以最終讓它在Silverlight中工作。如果你這樣做,你可以在Silverlight中進行驗證,並調用操作。但是,在您的模型和元數據項目中,不會像Jeff的帖子那樣。

編輯:我發現了一個更清潔,更好的方式

你可以在Silverlight的客戶端創建一個部分類,並執行以下操作

public partial class User 
    { 
     partial void OnUserNameChanging(string value) 
     { 
      //must be new to check for this validation rule 
      if(EntityState == EntityState.New) 
      { 
       var ctx = new UserContext(); 
       ctx.IsValidUserName(value).Completed += (s, args) => 
       { 
        InvokeOperation invop = (InvokeOperation) s; 
        bool isValid = (bool) invop.Value; 

        if(!isValid) 
        { 
         ValidationResult error = new ValidationResult(
          "Username already exists", 
          new string[] {"UserName"}); 
         ValidationErrors.Add(error; 
        } 
       }; 
      } 
     } 
    } 

這是WCF RIA服務生成的方法並且可以很容易地被取消,您可以像這樣添加帶外驗證。這是一個更簡潔的方式來做到這一點,但現在這種驗證只存在於Silverlight客戶端。

希望這會有所幫助

+0

你真棒 – ravella 2012-04-06 15:07:39

相關問題