在不使用DataContractAttribute的情况下强制NetDataContractSerializer中的顺序

时间:2018-02-01 17:22:04

标签: c# serialization datacontract datamember netdatacontractserializer

我想强制NetDataContractSerializer按特定顺序写属性值,因为序列化程序按字母顺序写入它们。

我知道我可以通过向这些属性添加[DataMember(Order = X)]属性来实现此目的,但这只有在我将[DataContract]属性添加到我正在序列化的类时才有效。

很遗憾,我无法将[DataContract]属性添加到此类,因为它的基类没有。{/ p>

还有其他方法可以强制执行订单吗?

1 个答案:

答案 0 :(得分:2)

我想出了使用自己的ISerializationSurrogate的想法,我可以自己处理正在序列化的属性。

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

然后我将序列化代理分配给序列化器。

var formatter = new NetDataContractSerializer();
var surrogateSelector = new SurrogateSelector();
surrogateSelector.AddSurrogate(typeof(T), new StreamingContext(StreamingContextStates.All), new MySerializationSurrogate<T>());
formatter.SurrogateSelector = surrogateSelector;

一切都像地狱一样。

注意T是被序列化/反序列化的对象的类型。