2010-07-19 3 views
3

Я пытаюсь сериализовать сложный граф, используя C# mono (mono v2.6), граф имеет двунаправленные ссылки и есть объекты, которые создают круговые зависимости. После выполнения некоторых чтении я попытался установить флаг preserveObjectReferences, который должен разрешить циклические ссылки необходимо установить (этот конструктор):Поддерживает ли mono DataContractSerializer флажок preserveObjectReferences?

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

Исключение я получаю выглядит следующим образом:

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

Кто-нибудь везло сериализация сложных объектов в моно? Согласно документации здесь: http://go-mono.com/status/status.aspx?reference=3.5&profile=2.0&assembly=System.Runtime.Serialization Эти конструкторы поддерживаются.

+0

Я не могу ответить на ваш вопрос, но я мог бы рекомендовать вам попробовать код с последним Моно и посмотрите, работает ли он там. В WCF многое исправлено с 2.6 ... – TheNextman

ответ

6

EDIT: Из того, что я вижу, вы также должны установить IsReference = истинное свойство в DataContractAttribute см here и here

IsReference получает или задает значение, указывающее, следует ли сохранить ссылку на объект данных. PreserveObjectReferences должно получить значение, указывающее, следует ли использовать нестандартные XML-конструкции для сохранения опорных данных объекта.

Mono делает сериализации поддержки контракта данных, но так как это замечание, сделанное в говорит источник, есть работа, которую нужно сделать:

([MonoTODO («Поддержка массивов, поддержка Сериализуемым, поддержка SharedType, использование DataContractSurrogate») ] - preserveObjectReferences указывает, должен ли вывод содержать ms: Id или нет.)

Попробуйте прочитать документацию по .NET Framework для сериализации контрактных данных here и сравнить ее с исходным кодом, доступным в Mono, это прояснит ситуацию.

сделать то же для других System.Runtime.Serialization Namespaces, прочитайте документацию из MSDN и сравнить с тем, что вы получили в Mono namespaces

Исходный код System.Runtime.Serialization Namespaces в Mono доступна here и источник DataContractSerializer Класс here, который содержит следующие вещи, которые интересуют:

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

// метод 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); 
    } 

// в preserveObjectReferences() недвижимость

public bool PreserveObjectReferences { 
    get { return preserve_refs; } 
    } 

По this:

** По умолчанию ссылки на объекты не сохраняются в DataContractSerializer; Значения объекта, на который ссылаются несколько раз, сериализуются несколько раз. Если объект является частью взаимной (циклической) ссылки (например, круговой связанный список), исключение генерируется во время сериализации.

DataContractSerializer может быть сделано, чтобы сохранить ссылку на объект, передавая верно для параметра PreserveObjectReference при построении DataContractSerializer **:

new DataContractSerializer(type, name, ns, knownTypes, 
      0x7FFF /*maxObjectsInGraph*/, 
      false/*ignoreExtensionDataObject*/, 
      true/*preserveObjectReferences*/, 
      null/*dataContractSurrogate*/); 
Смежные вопросы