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!
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With