Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在WCF响应中序列化嵌套类型?_C#_.net_Wcf_Serialization_Messagecontract - Fatal编程技术网

C# 如何在WCF响应中序列化嵌套类型?

C# 如何在WCF响应中序列化嵌套类型?,c#,.net,wcf,serialization,messagecontract,C#,.net,Wcf,Serialization,Messagecontract,场景: 我正在创建一个公开用户数据的WCF服务。用户的实例具有名为Role的属性。如果我省略了此属性,则服务有效;如果不忽略该属性,服务将失败。下面是代码的(非常)简化表示 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1, EmitConformanceClaims = true)] [ServiceContract(Name = "IService", Namespace = "http://local/version1/

场景:

我正在创建一个公开用户数据的WCF服务。用户的实例具有名为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; }
}
问题的根源在于角色嵌套/嵌入在用户类中(您如何称呼它…)。似乎它不能以这种方式序列化

如果搜索可能的解决方案,但似乎找不到正确的解决方案。我在合同和用户类中尝试了KnownTypeAttribute,但都没有成功

问题:

  • 在用户类中包含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属性指定静态未知的类型。“


忘了在帖子中提到,用户和角色类是在EntityFramework4.1中使用的。我没有猜到这应该是个问题,但显然是这样。

将datacontract属性添加到类中,并将datamember属性添加到要序列化的每个属性中

您需要像这样创建
用户
角色
数据契约:

    [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; } 
    } 
[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知道如何序列化以及序列化什么。在MSDN上有一个混合
MessageContract
DataContract
的例子,正如您在案例中所做的那样:

可能与代理创建有关

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

请描述服务如何失败。您遇到了什么异常?您是否尝试放置[DataContract]和[DataMember]属性?您应该添加DataContract和DataMemberattributes@Monty:啊,也许我应该更清楚:)我的意思是,你可以在服务器端添加一些测试代码,手动序列化返回对象,捕获序列化程序引发的任何异常,并在调试模式下对其进行检查。@Monty:使用这种方法的原因是,据我所知,没有简单的方法可以查看序列化响应时发生的异常。您可以在服务上启用日志记录,但是您会在“事后”捕获它,并且无法检查应用程序或异常。不幸的是,它有相同的结果。尝试将角色更改为角色,您也需要
角色
属性上的DataMember。是的,Anthony write只是将角色更改为角色与@GregoryNozik的答案略有不同。我已经试过了,但是我也得到了和没有一样的结果。。。我想我忽略了一些东西,但不知道是什么。最终的解决方案可以完全完成,用户/角色类上没有DataContract/DataMember属性。不过我喜欢你的帖子,MSDN链接也很好地解释了这一点。正如《开始》帖子的“更新1”中所述,我忘了提到我使用的是实体框架。只有当我测试序列化过程(也请参见“更新#1”)时,我才发现它与实体框架有关。您建议的这条代码规则正是解决方案!!它不会根据用户/角色生成任何其他类。唯一的问题是,在查询时必须包含“角色”实体。