简体   繁体   English

单声道是否通过带有saveObjectReferences标志支持DataContractSerializer?

[英]Does mono support DataContractSerializer with the preserveObjectReferences flag?

I am trying to serialize a complex graph using c# mono (mono v2.6) the graph has bi-directional links and there are objects which create circular dependencies. 我正在尝试使用c#mono(mono v2.6)序列化复杂的图形,该图形具有双向链接,并且存在创建循环依赖项的对象。 After doing some reading I tried setting the preserveObjectReferences flag which should allow circular references to be set (this constructor): 经过一番阅读后,我尝试设置prepareObjectReferences标志,该标志应允许设置循环引用(此构造函数):

public DataContractSerializer(
 Type type,
 IEnumerable<Type> knownTypes,
 int maxItemsInObjectGraph,
 bool ignoreExtensionDataObject,
 bool preserveObjectReferences,
 IDataContractSurrogate dataContractSurrogate
)

The exception I get is as follows: 我得到的异常如下:

SerializationException: Circular reference of an object in the object graph was found: 'ShaderMasterNode' of type ShaderMasterNode

Has anyone had any luck serializing complex objects in mono? 有没有人幸运地在mono中序列化复杂对象? According to the documentation here: http://go-mono.com/status/status.aspx?reference=3.5&profile=2.0&assembly=System.Runtime.Serialization These constructors are supported. 根据此处的文档: http : //go-mono.com/status/status.aspx?reference=3.5&profile=2.0&assembly=System.Runtime.Serialization支持这些构造函数。

EDIT: From what I see you also need to set the IsReference = true property in the DataContractAttribute , see here and here 编辑:据我所知,您还需要在DataContractAttribute中设置IsReference = true属性,请参见此处此处

IsReference gets or sets a value that indicates whether to preserve object reference data. IsReference获取或设置一个值,该值指示是否保留对象参考数据。 PreserveObjectReferences should get a value that specifies whether to use non-standard XML constructs to preserve object reference data. PreserveObjectReferences应该获得一个值,该值指定是否使用非标准XML构造来保留对象引用数据。

Mono does support Data Contract Serialization but as this comment made in the source tells, there is some work to be done : Mono确实支持数据合同序列化,但是正如在源代码中的注释所表明的那样,还有一些工作要做:

([MonoTODO ("support arrays; support Serializable; support SharedType; use DataContractSurrogate")] - preserveObjectReferences indicates that whether the output should contain ms:Id or not. ) ([[MonoTODO(“支持数组;支持可序列化;支持SharedType;使用DataContractSurrogate”)]-prepareObjectReferences指示输出是否应包含ms:Id。)

Try to read the .NET Framework documentation for Data Contract Serialization here and compare it with the source code available in Mono, this will clarify things. 尝试在此处阅读.NET Framework的数据合同序列化文档,并将其与Mono中可用的源代码进行比较,这将使事情变得清晰。

Also do the same for other System.Runtime.Serialization Namespaces, read the documentation from MSDN and compare with what you got in Mono namespaces 也对其他System.Runtime.Serialization命名空间执行相同的操作,从MSDN中阅读文档,并与在Mono命名空间中获得的内容进行比较

The source code for System.Runtime.Serialization Namespaces in Mono is available here and the DataContractSerializer Class source is here which contains the following things that interest: Mono中System.Runtime.Serialization命名空间的源代码在此处可用,DataContractSerializer类源在此处包含以下有趣的内容:

// Three constructors with this property

    public DataContractSerializer (Type type,
   IEnumerable<Type> knownTypes,
   int maxObjectsInGraph,
   bool ignoreExtensionDataObject,
   **bool preserveObjectReferences,**
   IDataContractSurrogate dataContractSurrogate)
   : this (type, knownTypes)
  {
   Initialize (maxObjectsInGraph,
    ignoreExtensionDataObject,
    **preserveObjectReferences,**
    dataContractSurrogate);
  }

  public DataContractSerializer (Type type,
   string rootName,
   string rootNamespace,
   IEnumerable<Type> knownTypes,
   int maxObjectsInGraph,
   bool ignoreExtensionDataObject,
   **bool preserveObjectReferences,**
   IDataContractSurrogate dataContractSurrogate)
   : this (type, rootName, rootNamespace, knownTypes)
  {
   Initialize (maxObjectsInGraph,
    ignoreExtensionDataObject,
    **preserveObjectReferences,**
    dataContractSurrogate);
  }

  public DataContractSerializer (Type type,
   XmlDictionaryString rootName,
   XmlDictionaryString rootNamespace,
   IEnumerable<Type> knownTypes,
   int maxObjectsInGraph,
   bool ignoreExtensionDataObject,
   **bool preserveObjectReferences,**
   IDataContractSurrogate dataContractSurrogate)
   : this (type, rootName, rootNamespace, knownTypes)
  {
   Initialize (maxObjectsInGraph,
    ignoreExtensionDataObject,
    **preserveObjectReferences,**
    dataContractSurrogate);
  }

// the Initialize() method // Initialize()方法

    void Initialize (
   int maxObjectsInGraph,
   bool ignoreExtensionDataObject,
   bool preserveObjectReferences,
   IDataContractSurrogate dataContractSurrogate)
  {
   if (maxObjectsInGraph < 0)
    throw new ArgumentOutOfRangeException ("maxObjectsInGraph must not be negative.");
   max_items = maxObjectsInGraph;
   ignore_ext = ignoreExtensionDataObject;
   preserve_refs = preserveObjectReferences;
   surrogate = dataContractSurrogate;

   PopulateTypes (Type.EmptyTypes);
  }

// the preserveObjectReferences() property // prepareObjectReferences()属性

    public bool PreserveObjectReferences {
   get { return preserve_refs; }
  }

According to this : 根据

**By default object references are not preserved by the DataContractSerializer; **默认情况下,DataContractSerializer不会保留对象引用; Values of an object referenced multiple times is serialized multiple times. 多次引用的对象的值被序列化多次。 If the object is part of mutual (cyclic) reference (eg circular linked list) an exception is thrown during serialization. 如果对象是相互(循环)引用(例如,循环链表)的一部分,则在序列化期间会引发异常。

DataContractSerializer can be made to preserve object reference by passing true for parameter PreserveObjectReference when constructing DataContractSerializer** : 在构造DataContractSerializer **时,可以通过为参数PreserveObjectReference传递true来使DataContractSerializer保留对象引用:

new DataContractSerializer(type, name, ns, knownTypes,
            0x7FFF /*maxObjectsInGraph*/,
            false/*ignoreExtensionDataObject*/,
            true/*preserveObjectReferences*/,
            null/*dataContractSurrogate*/);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM