This should be pretty straight forward but after deserializing my business objects using DataContractSerializer
all the custom collections inside them turned to read-only.
To be exact i am trying to manipulate the collection after deserialization by swapping the items inside collection but this is throwing exception saying Collection is read-only. However, before serialization, everything is fine.
An unhandled exception of type 'System.NotSupportedException' occurred in mscorlib.dll Additional information: Collection is read-only.
This is how i have decorated my custom collection class.
[Serializable]
[DataContract]
[KnownType(typeof(RuleBase))]
[KnownType(typeof(RuleSet))]
public class GenericRuleCollection : ObservableCollection<IRule>
{
//...
}
This is the way i have decorated my business object class.
[Serializable]
[DataContract]
public class RuleSet : GenericRuleContainer
{
//...
}
[Serializable]
[DataContract(IsReference = true)]
public abstract class GenericRuleContainer : GenericRule, IRuleContainer
{
private GenericRuleCollection _children;
[DataMember]
public GenericRuleCollection Children
{
get { return _children; }
set { SetProperty(ref _children, value); }
}
//...
}
Serialization and Deserialization piece of code:
public class DataContractSerializer<T>
{
public void SerializeToFile(string fileName, T obj)
{
var serializer = new DataContractSerializer(typeof(T));
using (FileStream fs = File.Open(fileName, FileMode.Create))
{
serializer.WriteObject(fs, obj);
}
}
public T DeserializeFromFile(string fileName)
{
var serializer = new DataContractSerializer(typeof(T));
using (FileStream fs = File.Open(fileName, FileMode.Open))
{
object s2 = serializer.ReadObject(fs);
return (T)s2;
}
}
}
Well after some random research on google i could able to fix this issue by changing attribute decoration from [DataContract]
to [CollectionDataContract]
on my custom collection class.
[Serializable]
[CollectionDataContract]
[KnownType(typeof(RuleBase))]
[KnownType(typeof(RuleSet))]
public class GenericRuleCollection : ObservableCollection<IRule>
{
//...
}