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; }
}

问题的根源是角色嵌套/嵌入(你怎么称呼它......)在用户类中。好像不能这样序列化。

如果搜索可能的解决方案,但似乎找不到正确的解决方案。我已经在合同以及 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();
}

这会导致 InvalidOperationException 出现消息“生成 XML 文档时出错”。此异常具有 InvalidOperationException(再次)作为 InnerException,消息为“类型 System.Data.Entity.DynamicProxies.User_FAC9CE2C5C9966932C0C37E6677D35437C14CDD08‌​884AD33C546805E62B7101E 不是预期的。使用 XmlInclude 或 SoapInclude 属性来指定静态未知的类型。

忘记在帖子中提到,User 和 Role 类在 Entity Framework 4.1 中使用。没有猜测应该是一个问题,但显然它确实如此。

4

4 回答 4

2

您将需要像这样制作UserRoleDataContracts:

[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 知道序列化的方式和内容。有一个混合MessageContract和的示例DataContract,正​​如您在您的情况下所做的那样,在 MSDN 上:http: //msdn.microsoft.com/en-us/library/ff648210.aspx

于 2011-09-21T12:51:36.623 回答
2

可能与代理创建有关。

尝试设置以下内容: context.ContextOptions.ProxyCreationEnabled = false;

于 2011-09-21T13:19:53.033 回答
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 属性添加到要序列化的每个属性的类和数据成员属性

于 2011-09-21T12:44:44.840 回答