我正在尝试使用与DataSerializer
一起使用的标准wcf
序列化一组对象。
对象结构:
[KnownType(typeof(PersonnelClassProperty))]
[KnownType(typeof(ResourceClassProperty))]
[KnownType(typeof(Person))]
[KnownType(typeof(PersonProperty))]
[KnownType(typeof(ResourceDefinitionProperty))]
[DataContract]
public class Person: ResourceDefinition
{
[DataMember]
public guid id {get; set;}
[DataMember]
public IList<PersonProperty> personProperties {get; set;}
[DataMember]
public IList<PersonnelClass> personnelClasses {get; set;}
}
PersonProperty:ResourceDefinitionProperty
PersonnelClass:ResourceClass
PersonnelClassPoperty:ResourceClassProperty
使用Nhibernate
映射Above结构。所以Base类是abstract classes
,其基本属性我们覆盖到主类中。我们正在使用它,所以我们可以使用泛型类来调用Nhibernate
中的CRUD函数。
这带来的第一个问题是循环引用,我们解决了这个问题。通过重置对象列表,我们消除了循环引用问题。
我们还遍历属性和关联的类属性来获取它们,因为它们通过nHibernate
延迟加载
这允许我生成一些测试数据。我们现在有personnelclass
个personnelclassproperty
。这些都可以自行检索。接下来我们有一个person
。我们添加了对personnelclass
和personnelclassproperty
的引用。在数据库中,我们有一个额外的表,其中包含人与personnelclass
之间的链接的引用,因为这是many-to-many relationShip
。 personProperty
引用了单个personnelClassproperty
,因此FK
就足够了。
这里,我们遇到第二个问题,发生序列化异常:
不希望'PersonnelClassPropertyProxy'与数据合同名称'PersonnelClassPropertyProxy:http://schemas.datacontract.org/2004/07/'。考虑使用DataContractResolver或将任何静态未知的类型添加到已知类型列表中 - 例如,使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。
所以从第一行中提到的问题中我开始将[DataContract]
,[DataMember]
和[KnownType(typeof(T))]
属性添加到上面提到的类中。其中T
当然是正确的类型。
我们通过wcf将人物对象发送给接收方,如果personProperty
和personnelClassProperty
之间没有链接,则可以正常工作,但如果我们添加personproperty
}通过指向PersonnelClassProperty
的链接,我们得到了上述异常。
我在网上看到的所有示例和问题都以相同的方式工作
具体而言;我究竟做错了什么?或者我忘记了什么?我将尝试使用更多代码更新问题,以说明我们使用的对象。
编辑:我更新了Person
对象的结构,以显示我对KnownTypes
所做的工作。请注意,这也包含personnelClassProperty
类型,我也为PersonProperty
对象执行了此操作,因为这是包含PersonnelClassProperty
对象的实际类,但是{{1}的列表在personProperties
中使用。}这也不起作用。
答案 0 :(得分:1)
我找到了解决方案。由于我们使用的是NHibernate
,因此我们lazy loading
personnelClassProperty
进入Personproperty
,最终进入Person
。这导致serialization exception
。
实际上有2个解决方案来解决异常:
1:您可以在对象到NHibernate的映射中设置Not.LazyLoad()
属性而不是LazyLoad()
2:您可以启用Lazyload()
属性,而是在尝试序列化之前从对象中获取项目并对其执行某些操作。仅创建一个新变量是不够的:
PersonnelClassProperty classproperty = personProperty.PersonnelClassProperty;
你真的必须对内部对象做一些事情,如下:
PersonnelClassProperty classProperty = personProperty.PersonnelClassProperty;
System.Diagnostics.Debug.WriteLine(classproperty.Dbid);
我们目前选择使用.Not.Lazyload()
选项