DataContractSerializer: Deserialized object with reference id 'xyz' not found in stream. How to recover data?
Asked Answered
G

1

11

I have persisted an array of objects to a file using DataContractSerializer. It has been working fine until recently when I started getting the following message.

Deserialized object with reference id '15' not found in stream
   bei System.Runtime.Serialization.XmlObjectSerializerReadContext.GetExistingObject(String id, Type type, String name, String ns)
   bei ReadAbgleichSettingsFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )
   bei System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
   bei System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
   bei System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract)
   bei System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(XmlReaderDelegator xmlReader, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, String name, String ns)
   bei ReadUnitOfTestFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )
   bei System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
   bei System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
   bei System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract)
   bei System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(XmlReaderDelegator xmlReader, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, String name, String ns)
   bei ReadArrayOfBaseModuleFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString , XmlDictionaryString , CollectionDataContract )
   bei System.Runtime.Serialization.CollectionDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
   bei System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
   bei System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract)
   bei System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
   bei System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
   bei System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
   bei System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlReader reader)
   bei Pruef.Net.Model.ModuleManager.LoadModules() in D:\\my_workspaces\\visualstudioprojects\\Pruef.Net\\Pruef.Net\\PruefMvvm\\Model\\ModuleManager.cs:Zeile 626.

The problem appears to be associated with the class AbgleichSettings.

    [DataContract(Name = "AbgleichSettings")]
public class AbgleichSettings
{
    #region PROPERTIES
    /// <summary>
    /// Enable feature
    /// </summary>
    [DataMember(Name = "IsEnabled")]
    public bool IsEnabled { get; set; }

    /// <summary>
    /// Display units after value
    /// </summary>
    [DataMember(Name="Units", IsRequired=false)]
    public string Units { get; set; }

    /// <summary>
    /// Multiply value by factor
    /// </summary>
    [DataMember(Name = "Factor")]
    public double Factor { get; set; }

    /// <summary>
    /// Show decimal places 0-3
    /// </summary>
    [DataMember(Name = "DecimalPlaces")]
    public int DecimalPlaces { get; set; }
    #endregion

    [OnDeserializing]
    void OnDeserializing(StreamingContext context)
    {
        IsEnabled = false;
        Units = "";
        Factor = 1;
        DecimalPlaces = 0;
    }

    public AbgleichSettings()
    {
        IsEnabled = false;
        Units = "";
        Factor = 1;
        DecimalPlaces = 0;
    }

}

Note the DataMember.Name attributes were added later as I attempted to solve the problem.

I looked in the XML and saw that the object with Id="15" is a {Comment} element which is a string property in a different class.

<Header>
  <ChangeInfo z:Id="14">
    <Author i:nil="true" />
    <Comment z:Id="15"></Comment>
    <Date>0001-01-01T00:00:00</Date>
  </ChangeInfo>
</Header>
....
<Abgleich z:Id="34">
  <DecimalPlaces>0</DecimalPlaces>
  <Factor>1</Factor>
  <IsEnabled>false</IsEnabled>
  <Units z:Ref="15" i:nil="true" />
</Abgleich>

** Serializer **

return new DataContractSerializer(Modules.GetType(), null,
                int.MaxValue /*maxItemsInObjectGraph*/,
                true /*ignoreExtensionDataObject*/,
                true /*preserveObjectReferences : this is where the magic happens */,
                null /*dataContractSurrogate*/);

What might have gone wrong here? What can I do to recover from this error?

Thanks!

Geomorphology answered 5/9, 2012 at 5:45 Comment(2)
I hope you are attempting to deserialize this XML using WCF only and the DataContractSerializer you are instantiating has preserveObjectReferences parameter set to true. Also the id 15 you are seeing is not really the 'Comment' property but I think it is referring to empty string in your XMLCornish
@Amit - the preserveObjectReferences parameter is set to true. What do you mean by 'deserialize this XML using WCF only'? I serialize and deserialize using DataContractSerializer (see Edit)Geomorphology
G
2

After some experimentation, I have been able to get it working again but I don't understand exactly what the problem is.

The class 'ModuleHeader' originally just had the attribute [Serializable] and its properties had the attribute [DataMember]. Recently, I added [DataContract] to the class (seemed appropriate) and this is what caused the problem. In the OnSerialized event I noticed that the instance had not been initialised and therefore the object with the missing Id was not being created. Once I removed the [DataContract] attribute the deserialization started working again.

I will post a new question...

Geomorphology answered 10/9, 2012 at 6:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.