gpt4 book ai didi

c# - json 从遗留属性名称反序列化

转载 作者:太空狗 更新时间:2023-10-29 21:21:53 24 4
gpt4 key购买 nike

如何设置 Newtonsoft.Json 以使用旧成员名称反序列化对象,但使用当前成员名称对其进行序列化?

编辑:要求从正在序列化/反序列化的类中删除过时的成员。

这是一个需要序列化和反序列化的示例对象。我已经为一个属性提供了一个属性,其中包含一个名称列表,它可能在过去被序列化。

[DataContract]
class TestObject {
[LegacyDataMemberNames("alpha", "omega")]
[DataMember(Name = "a")]
public int A { get; set; }
}

我想始终使用名称“a”进行 json 序列化,但能够从任何旧名称(包括“alpha”和“omega”以及当前名称“a”)反序列化为一个属性

最佳答案

这可以通过自定义 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
{
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;
}
}

然后将属性添加到您的类型中,如问题所示:

[DataContract]
class TestObject
{
[LegacyDataMemberNames("alpha", "omega")]
[DataMember(Name = "a")]
public int A { get; set; }
}

构造和配置 LegacyPropertyResolver 实例,例如如下:

static IContractResolver legacyResolver = new LegacyPropertyResolver 
{
// Configure as required, e.g.
// NamingStrategy = new CamelCaseNamingStrategy()
};

然后在settings中使用它:

var settings = new JsonSerializerSettings { ContractResolver = legacyResolver };
var deserialized = JsonConvert.DeserializeObject<TestObject>(jsonString, settings);

注意事项:

演示 fiddle here .

关于c# - json 从遗留属性名称反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33155458/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com