2

シナリオ:

ユーザー データを公開する WCF サービスを作成中です。User のインスタンスには、Role というプロパティがあります。このプロパティを省略した場合、サービスは機能します。プロパティを省略しないと、サービスは失敗します。以下は、コードの(非常に)簡略化された表現です。

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1, EmitConformanceClaims = true)]
[ServiceContract(Name = "IService", Namespace = "http://local/version1/")]
public interface IService : IDisposable
{
   [WebMethod]
   [SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
   [OperationContract(Action = "http://local/version1/GetUser")]
   GetUserResponse GetUser(GetUserRequest request);
}

[MessageContract(IsWrapped = true, WrapperName = "GetUserResponse")]
[XmlRoot("GetUserResponse")]
public class GetUserResponse
{
   [XmlElement(ElementName = "User")]
   [MessageBodyMember(Order = 0)]
   public User User { get; set; }
}

public class User
{
   public int UserId { get; set; }

   public string UserName { get; set; }

   public Role Role { get; set; }
}

public class Role
{
   public string Name { get; set; }
}

問題の根本は、Role が User クラスにネスト/埋め込まれていることです (どのように呼びますか...)。この方法ではシリアル化できないようです。

可能な解決策を検索しても、正しい解決策が見つからないようです。コントラクトと User クラスで KnownTypeAttribute を使用して何かを試しましたが、うまくいきませんでした。

質問:

  • User クラスに Role プロパティを含める適切な方法は何ですか?
  • 機能させるには、どの属性をどこに追加する必要がありますか?
  • シリアル化可能にするために実装できるインターフェイスはありますか?

返信ありがとうございます。

更新 #1

@CPX の提案の後、サーバー側で追加のテスト コードを作成しました。

using (StringWriter stringWriter = new StringWriter())
{
   XmlSerializer serializer = new XmlSerializer(typeof(GetUserResponse));
   serializer.Serialize(stringWriter, response);
   string result = stringWriter.ToString();
}

これにより、「XML ドキュメントの生成中にエラーが発生しました」というメッセージを含む InvalidOperationException が発生します。この例外には、InnerException として (再び) InvalidOperationException があり、メッセージ「型 System.Data.Entity.DynamicProxies.User_FAC9CE2C5C9966932C0C37E6677D35437C14CDD08‌ 884AD33C546805E62B7101E は想定されていませんでした。XmlInclude または SoapInclude 属性を使用して、静的に認識されていない型を指定します。

投稿で言及するのを忘れていましたが、User クラスと Role クラスは Entity Framework 4.1 内で使用されます。問題になるとは思いませんでしたが、どうやら問題があるようです。

4

4 に答える 4

2

おそらくプロキシの作成と関係があります。

次のように設定してみてください: context.ContextOptions.ProxyCreationEnabled = false;

于 2011-09-21T13:19:53.033 に答える
2

User次のようにRoleDataContractsを作成する必要があります。

[DataContract]
public class User
{
   [DataMember]
   public int UserId { get; set; }

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

   [DataMember]
   public Role Role { get; set; }
}

[DataContract]
public class Role
{
   [DataMember]
   public string Name { get; set; }
}

これにより、WCF はシリアル化する方法と対象を認識できます。あなたのケースで行っているように、MSDNMessageContractの混合の例があります: http://msdn.microsoft.com/en-us/library/ff648210.aspxDataContract

于 2011-09-21T12:51:36.623 に答える
1
    [DataContract]  
    public class User {   

    [DataMember]
    public int UserId { get; set; }     

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

    [DataMember]    
    public Role role { get; set; } }  

    [DataContract] 
    public class Role
    {
       [DataMember]
       public string Name { get; set; } 
    } 
于 2011-09-21T12:47:49.727 に答える
0

クラスに datacontract 属性を追加し、シリアル化する各プロパティに datamember 属性を追加します。

于 2011-09-21T12:44:44.840 に答える