2011-06-21 26 views
4

我有DataContract類,它具有List<AnotherObject>類型的屬性。 AnotherObject也用DataContract標記。出於某種原因,該屬性來自wcf服務爲空,儘管我將它填充到服務器。這是由設計嗎?wcf新手問題:數組作爲屬性

你在這裏。類定義:

[DataContract] 
    public class UserInfo 
    { 
     [DataMember] 
     public decimal UserID 
     { 
      get; 
      protected internal set; 
     } 

     [DataMember] 
     public string UserName 
     { 
      get; 
      protected internal set; 
     } 

     [DataMember] 
     public string Pswd 
     { 
      get; 
      protected internal set; 
     }  

     [DataMember] 
     public List<decimal> RoleID 
     { 
      get; 
      protected internal set; 
     } 

     List<UserRole> userRolesTable = new List<UserRole>(); 
     [DataMember] 
     public List<UserRole> UserRoles 
     { 
      get 
      { 
       return userRolesTable; 
      } 
      protected internal set { } 
     }  
    } 



[DataContract] 
    public class UserRole 
    { 
     [DataMember] 
     public decimal ROLEID { get; internal set; } 

     [DataMember] 
     public string ROLE_CODE { get; internal set; } 

     [DataMember] 
     public string ROLE_DESCRIPTION { get; internal set; } 

     [DataMember] 
     public decimal FORMID { get; internal set; } 

     [DataMember] 
     public string FORMCODE { get; internal set; } 

     [DataMember] 
     public string FORMNAME { get; internal set; } 
    } 

UserRoles屬性爲空。

+2

你能發表一些代碼嗎?這聽起來不像是按照設計。 – Peter

+0

Is List 屬性是否標有[DataMember]屬性?代碼會有幫助。 –

+0

是的,這是從附加代碼中可以看到的。 – Nickolodeon

回答

0

需要實現的制定者......

protected internal set { userRolesTable = value; } 
+0

我會嘗試。你能告訴我爲什麼? – Nickolodeon

+0

Wcf測試客戶端填寫我的財產很好。這是實際的客戶端(Windows應用程序)收到壞ret值。 – Nickolodeon

+0

嘗試僅使用自動實現的屬性 - 並將其公開爲踢 - {get;私人設置;} – MattS423

1
List<UserRole> userRolesTable = new List<UserRole>(); 
[DataMember] 
public List<UserRole> UserRoles 
{ 
    get 
    { 
     return userRolesTable; 
    } 
    protected internal set { } 
} 

你的二傳手是空的。把一些

userRolesTable = value; 

另一件事,你的DataContract屬性都應該具有公共 setter方法。

+0

把一些setter不起作用。我也有名單(即[數據成員] 公開名單角色ID { 搞定; 保護的內部設置; })和填充只是受保護的二傳罰款。 – Nickolodeon

+0

將[DataMember]放在字段而不是屬性上? – DiVan

1

UserRoles屬性上的Setter設置爲internal。因爲WCF框架將設置屬性,所以放棄分配值,因爲它被列爲內部值。

http://connect.microsoft.com/data/feedback/details/625985/wcf-client-entities-with-internal-setters-and-internalsvisibletoattribute-on-asmbly-fail

爲此,您可以聯繫表明什麼,使用該財產的InternalsVisibleToAttribute屬性,但我從來沒有使用過。

更新 我想說的是,我敢打賭,序列化工作正常,因爲根據數據契約WCF框架是無法插入反序列化的值到宿主代碼,的內部二傳手節財產無法存取。使用InternalVisibleTo屬性通知WCF序列化框架訪問數據合同對象的客戶端版本的設置者。

+0

爲什麼然後列表序列化罰款?可能是B/C這是一種原始類型。 – Nickolodeon

+0

問題是您的包含類比通用類型列表更多。 WCF框架需要能夠設置和獲取屬性,因爲它通過Data Contract裝飾對象生成客戶端對象。想想這樣,WCF框架不知道你是否會使用你的數據合約對象作爲結果,或作爲參數。我希望有所幫助。 –

+0

這裏是另一篇關於使用InternalsVisibleTo屬性的博客文章:http://systemmetaphor.blogspot.com/2010/04/silverlight-serialization-avoiding.html –

3

你爲什麼讓RoleId屬性自動實現,但不是UserRoles?現在的代碼將不起作用,因爲你有一個空setter。您應該可能只是使用它的自動屬性:

[DataMember] 
public List<UserRole> UserRoles 
{ 
    get; set; 
}  

或者至少提供一個有意義的setter。您的setter不做任何事情,因此解序列器無法填充值。

0

基本上,它是一個序列化問題。我過去在代碼中遇到過這個問題,但這已經有一段時間了,所以請耐心等待。

首先,我們需要在WCF調用之前找出對象關係是否爲空,所以在調用之前和之後進行調試。

如果該對象被調用之前返回null,您有幾種選擇:

  1. 可以明確地使用.INCLUDE(「AnotherObject」)在您的DbContext來獲取對象。我通過讓我的Read方法使用了一個字符串數組,這個字符串包含了所有必需的對象。這比自動獲取所有對象更爲理想,因爲在序列化過程中,如果您將所有內容全部取出,那麼您可以很容易地結束整個數據庫的序列化,這會引發性能和安全問題等等。

  2. 另一種方法是通過在列表前添加關鍵字virtual來使用動態代理。但DataContractSerializer在序列化動態代理時存在問題,因此您需要實現使用ProxyDataContractResolver而不是DataContractResolver的屬性。該屬性需要應用於所有可以通過動態代理的OperationContracts。這會自動獲取所有對象引用,這可能是不好的編碼習慣,所以我建議採用上述方法。

    public class ApplyDataContractResolverAttribute : Attribute, IOperationBehavior 
    { 
    
        public ApplyDataContractResolverAttribute() { } 
    
        public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters) { } 
    
        public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy) 
        { 
        DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>(); 
        dataContractSerializerOperationBehavior.DataContractResolver = new ProxyDataContractResolver(); 
        } 
    
        public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch) 
        { 
        DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>(); 
        dataContractSerializerOperationBehavior.DataContractResolver = new ProxyDataContractResolver(); 
        } 
    
        public void Validate(OperationDescription description) { } 
    
    } 
    

編輯:另外,我認爲,你可以在數據合同制定者不會公開,因爲我做到這一點,它工作得很好:)。但是我會盡量讓你的二傳手公開,然後解決問題,然後回到一個受保護的二傳手,以便儘可能少地處理變量。

+0

謝謝,但這一切似乎都太複雜了。我想,一定有一些更簡單的方法。 – Nickolodeon

+0

順便說一句,它看起來像你對DataContractSerializer是正確的 - 只要該字段或屬性具有DataMember屬性,它並不關心具有用某些修飾符修飾的屬性或字段。 – Nickolodeon

+0

此外,在客戶端創建的代理對象將我的所有屬性「解開」爲公共屬性。所以如果我試圖將該對象保存回wcf,可能會出現問題。 wcf重新啓動後,問題似乎消失了。謝謝大家的意見。 – Nickolodeon