2012-02-21 2 views
2

J'ai rencontré une exception très intéressante en essayant de sérialiser un graphique EF 4 STE.EF DataContractSerializer Exception

 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) 

Mon code de sérialisation est assez simple:

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

Dans mon objet graphique, j'ai ajouté quelques entités enfant à une entité mère, et je l'ai découvert que si j'appelle. AcceptChanges() méthode d'extension sur le parent, tout sérialise très bien.

Est-ce que quelqu'un d'autre a rencontré quelque chose comme ça? Qu'est-ce qui pourrait en être la cause? Des idées sur comment je peux couler le coupable? Mise à jour: J'ai trouvé un link où quelqu'un d'autre avait un problème similaire. Ils ont dit que System.Runtime.Serialization.ObjectReferenceStack.EnsureSetAsIsReference) effectue une validation de cycle et pourrait trouver un problème.

Mise à jour 2: J'ai également trouvé que définir preserveObjectReferences à true dans le constructeur pour DataContractSerializer efface l'exception.

Mise à jour 3: terminée à l'aide de l'approche décrite dans this article pour appeler le constructeur DataContractSerializer surchargé avec preserveObjectReferences défini sur true. Cette résolu le problème, même si je ne peux toujours pas l'expliquer ...

Alors peut-être maintenant, ma question devient: Comment est preserveObjectReferences sur DataContractSerializer différent que d'avoir [DataContract (IsReference = true)] sur tous les STE?

Merci!

Répondre

1

Il semble que PreserveObjectReferences utilise des "constructions XML non standard" pour toutes vos classes, alors que isReference est la méthode SOAP standard, mais il doit être déclaré sur chaque classe où cela est nécessaire. J'ai eu le même problème et c'était parce que j'avais manqué de le mettre dans certaines classes. Le piège commun est que DataContractAttribute n'est pas hérité, vous devez donc le redéclairer (avec IsReference = true) pour chaque classe héritée.

Questions connexes