2011-06-21 8 views
4

私は、タイプがList<AnotherObject>のDataContractクラスを持っています。 AnotherObjectには、DataContractもマークされます。なんらかの理由で、このプロパティはw​​cfサービスからヌルとして取得されますが、サーバーに入力します。それは設計によるのですか?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プロパティはnullになります。あなたがセッターを実装する必要が

+2

コードを投稿できますか?これは設計上のようには聞こえません。 – Peter

+0

List プロパティは[DataMember]属性でマークされていますか?コードが役に立ちます。 –

+0

はい、それは添付のコードからわかるようにです。 – Nickolodeon

答えて

0

...

protected internal set { userRolesTable = value; } 
+0

私はそれを試みます。それはなぜですか? – Nickolodeon

+0

Wcfテストクライアントは私のプロパティをうまく埋めます。それは実際のクライアント(Windowsアプリ)が悪いret valを受け取ります。 – Nickolodeon

+0

自動実装されたプロパティだけを使って試してみてください。プライベートセット;} – MattS423

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

あなたのセッターは空です。いくつかの

userRolesTable = value; 

別のものを入れて、あなたのDataContractのプロパティは、公共セッターを持っている必要があります。

+0

セッターを置いても機能しません。および保護されたセッターとうまく充填私もリスト(すなわち、[データメンバー] 公衆リスト RoleIDを{; 保護された内部組 取得})を有します。 – 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フレームワークは、そのデータコントラクト修飾オブジェクトを介してクライアントサイドオブジェクトを生成するため、プロパティの設定と取得の両方の機能を必要とします。このように考えると、WCFフレームワークは、結果としてデータコントラクトオブジェクトを使用するかどうか、またはパラメータとして使用するかどうかを認識しません。私はそれが助けて欲しい –

+0

ここに、InternalsVisibleTo属性の使用に関する別のブログ記事があります:http://systemmetaphor.blogspot.com/2010/04/silverlight-serialization-avoiding.html –

3

なぜRoleIdプロパティを自動実装するのですか?UserRolesを使用しないようにしますか?空のセッターがあるため、そのままのコードは機能しません。

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

少なくとも、意味のあるセッターを提供するだけです。 setterは何もしないので、デシリアライザは値を設定できません。

0

基本的に、そのシリアル化の問題です。私は過去に私のコードでこの問題を抱えていましたが、それはしばらくしていましたので、私に同行してください。

まず、オブジェクトの関係がWCF呼び出しの前にヌルであるかどうかを調べる必要があるため、前と後のデバッグを入れてください。

オブジェクトは呼び出しの前にnullを返しされている場合、あなたはいくつかのオプションがあります:あなたは、明示的にオブジェクトを得るためにあなたのDbContextに.INCLUDE(「AnotherObject」)を使用することができます

  1. を。私はこれを使用して、私のReadメソッドに必要なすべてのオブジェクトを含めるために使用した文字列の配列を取るようにしました。これは、シリアル化中にすべてをとると、データベース全体がシリアライズされてしまうため、パフォーマンスやセキュリティなどの問題が発生するため、すべてのオブジェクトを自動的に取得するよりも理想的です。

  2. もう1つの方法は、リストの前にキーワードvirtualを追加して動的プロキシを使用することです。ただし、DataContractSerializerには動的プロキシのシリアル化に問題があるため、DataContractResolverの代わりにProxyDataContractResolverを使用する属性を実装する必要があります。この属性は、動的プロキシを渡すことができるすべての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