Reputation: 1111
I want to force the NetDataContractSerializer
to write property values in a specific order, because the serializer writes them in an alphabetic order.
I know I can achieve this by adding [DataMember(Order = X)]
attributes to these properties but this works only when I add [DataContract]
attribute to the class I am serializing.
Unfortunately, I can't add the [DataContract]
attribute to this class since its base class doesn't have one.
Is there another way to force the order?
Upvotes: 0
Views: 100
Reputation: 1111
I've came up with the idea of using own ISerializationSurrogate
where I can handle getting the properties that are being serialized myself.
private class MySerializationSurrogate<T> : ISerializationSurrogate
{
private IEnumerable<DataMemberAttribute> GetXmlAttribs(PropertyInfo p) => p.GetCustomAttributes(false).OfType<DataMemberAttribute>();
public void GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
{
var myobj = (T)obj;
foreach (var property in myobj.GetType().GetProperties().Where(p => GetXmlAttribs(p).Any()).OrderBy(p => GetXmlAttribs(p).First().Order))
{
info.AddValue(property.Name, property.GetValue(myobj));
}
}
public Object SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
var myobj = (T)obj;
foreach (var property in myobj.GetType().GetProperties().Where(p => GetXmlAttribs(p).Any()).OrderBy(p => GetXmlAttribs(p).First().Order))
{
property.SetValue(myobj, info.GetValue(property.Name, property.PropertyType));
}
return null;
}
}
Then I assign the serialization surrogate to the serializer.
var formatter = new NetDataContractSerializer();
var surrogateSelector = new SurrogateSelector();
surrogateSelector.AddSurrogate(typeof(T), new StreamingContext(StreamingContextStates.All), new MySerializationSurrogate<T>());
formatter.SurrogateSelector = surrogateSelector;
And everything works like hell.
NOTE that T
is the type of the object being serialized/deserialized.
Upvotes: 2