json从旧版属性名称反序列化

json从旧版属性名称反序列化,第1张

json从旧版属性名称反序列化

这可以通过custom来完成,可以

IContractResolver
通过扩展现有的解析器之一来创建,例如
DefaultContractResolver

[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple = false, Inherited = true)]public class LegacyDataMemberNamesAttribute : Attribute{    public LegacyDataMemberNamesAttribute() : this(new string[0]) { }    public LegacyDataMemberNamesAttribute(params string[] names)    {        this.Names = names;    }    public string [] Names { get; set; }}public class LegacyPropertyResolver : DefaultContractResolver{    // As of 7.0.1, Json.NET suggests using a static instance for "stateless" contract resolvers, for performance reasons.    // http://www.newtonsoft.com/json/help/html/ContractResolver.htm    // http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm    // "Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance."    static LegacyPropertyResolver instance;    static LegacyPropertyResolver() { instance = new LegacyPropertyResolver(); }    public static LegacyPropertyResolver Instance { get { return instance; } }    protected LegacyPropertyResolver() : base() { }    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)    {        var properties = base.CreateProperties(type, memberSerialization);        for (int i = 0, n = properties.Count; i < n; i++)        { var property = properties[i]; if (!property.Writable)     continue; var attrs = property.AttributeProvider.GetAttributes(typeof(LegacyDataMemberNamesAttribute), true); if (attrs == null || attrs.Count == 0)     continue; // Little kludgy here: use MemberwiseClone to clone the JsonProperty. var clone = property.GetType().GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); foreach (var name in attrs.Cast<LegacyDataMemberNamesAttribute>().SelectMany(a => a.Names)) {     if (properties.Any(p => p.PropertyName == name))     {         Debug.WriteLine("Duplicate LegacyDataMemberNamesAttribute: " + name);         continue;     }     var newProperty = (JsonProperty)clone.Invoke(property, new object[0]);     newProperty.Readable = false;     newProperty.PropertyName = name;     properties.Add(newProperty); }        }        return properties;    }}

请注意,此实现不需要类具有显式的数据协定属性注释。如果愿意,可以添加该限制。

然后将其与以下内容一起使用

JsonSerializerSettings

var settings = new JsonSerializerSettings { ContractResolver = LegacyPropertyResolver.Instance };

例如:

[DataContract]class TestObject{    [LegacyDataMemberNames("alpha", "omega")]    [DataMember(Name = "a")]    public int A { get; set; }}public static class JsonExtensions{    public static void RenameProperty(this JObject obj, string oldName, string newName)    {        if (obj == null) throw new NullReferenceException();        var property = obj.Property(oldName);        if (property != null)        { property.Replace(new JProperty(newName, property.Value));        }    }}public class TestClass{    public static void Test()    {        try        { TestInner();        }        catch (Exception ex)        { Debug.Assert(false, ex.ToString()); // No assert throw;        }    }    public static void TestInner()    {        var test = new TestObject { A = 42 };        var settings = new JsonSerializerSettings { ContractResolver = LegacyPropertyResolver.Instance };        var json = JObject.FromObject(test, JsonSerializer.CreateDefault(settings));        if (json.SelectToken("alpha") != null || json.SelectToken("omega") != null) throw new InvalidOperationException("Failed serialization");        Test(test, json);        json.RenameProperty("a", "alpha");        Test(test, json);        json.RenameProperty("alpha", "omega");        Test(test, json);    }    private static void Test(TestObject test, JObject json)    {        var test1 = json.ToObject<TestObject>(JsonSerializer.CreateDefault(new JsonSerializerSettings { ContractResolver = LegacyPropertyResolver.Instance }));        if (test1.A != test.A) throw new InvalidOperationException("Failed deserialization");        Console.WriteLine("Successfully deserialized: " + json.ToString(Formatting.None));        Debug.WriteLine("Successfully deserialized: " + json.ToString(Formatting.None));    }}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5615195.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存