Исключение EF DataContractSerializer - PullRequest
2 голосов
/ 21 февраля 2012

Я столкнулся с очень интересным исключением, пытаясь сериализовать график EF 4 STE.

      System.IndexOutOfRangeException was caught
      Message=Index was outside the bounds of the array.
      Source=mscorlib
      StackTrace:
        Server stack trace: 
           at System.Runtime.Serialization.ObjectReferenceStack.EnsureSetAsIsReference(Object obj)
           at System.Runtime.Serialization.XmlObjectSerializerWriteContext.OnHandleIsReference(XmlWriterDelegator xmlWriter, DataContract contract, Object obj)
           at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
           ...
           at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter writer, Object graph)
           at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(Stream stream, Object graph)

Мой код сериализации довольно прост:

using (MemoryStream memoryStream = new MemoryStream())
{
    DataContractSerializer dc = new DataContractSerializer(data.GetType());
    dc.WriteObject(memoryStream, data);

    memoryStream.Flush();

    memoryStream.Position = 0;
    StreamReader reader = new StreamReader(memoryStream);
    var serializedObject = reader.ReadToEnd();
}

В моем графе объектов я добавил несколько дочерних объектов в родительский объект и обнаружил, что если я вызываю метод расширения .AcceptChanges () для родительского объекта, все сериализуется очень хорошо.

Кто-нибудь еще сталкивался с чем-то подобным? Что может быть причиной? Любые идеи о том, как я могу сбить преступника?

Обновление: я нашел ссылку , где у кого-то еще была похожая проблема. Они сказали, что System.Runtime.Serialization.ObjectReferenceStack.EnsureSetAsIsReference) выполняет некоторую проверку цикла и может найти проблему.

Обновление 2: я также обнаружил, что установка для preserveObjectReferences значения true в конструкторе для DataContractSerializer очищает исключение.

Обновление 3: закончено с использованием подхода, описанного в этой статье , для вызова перегруженного конструктора DataContractSerializer с preserveObjectReferences, установленным в значение true. Это исправило проблему, хотя я до сих пор не могу ее объяснить ...

Так что, может быть, теперь мой вопрос звучит так: Чем preserveObjectReferences в DataContractSerializer отличается от наличия [DataContract (IsReference = true)] для всех STE?

Спасибо!

1 Ответ

1 голос
/ 10 апреля 2013

Кажется, что PreserveObjectReferences использует "нестандартные конструкции XML" для всех ваших классов, в то время как isReference является стандартным способом SOAP, но его необходимо объявлять в каждом классе, где это необходимо.У меня была та же самая проблема, и это было, потому что я скучал по тому, чтобы поставить это на некоторых классах.Распространенной ловушкой является то, что DataContractAttribute не наследуется, поэтому его необходимо повторно объявить (с IsReference = true) для каждого унаследованного класса.

...