让我们说我有一些我以前用Json.Net序列化的类
public class BillingAddress
{
public string BillingCity { get; set; }
public string BillingState { get; set; }
public string BillingStreet { get; set; }
public string BillingZip { get; set; }
}
但是,我不得不回过头来将BillingStreet
更改为BillingStreet1
,然后再次更改为BillingStreetA
。我正在尝试在Json.Net中找到一种方法来支持属性或自定义转换器,该方法可以反序列化以前称为其他名称的属性,并且还支持具有多个不同的先前名称(例如在我的示例中) )。
我有一个依赖于以下属性的自定义转换器:
[JsonVersionedPropertyName("BillingStreetA", "BillingStreet1")]
public string BillingStreet { get; set; }
public class VersionedPropertyNameConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
//return objectType.IsClass;
return (objectType == typeof(IPaymentMethod));
}
public override bool CanWrite
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
object instance = objectType.GetConstructor(Type.EmptyTypes).Invoke(null);
PropertyInfo[] props = objectType.GetProperties();
var versionedProps = props.Where(x => Attribute.IsDefined(x, typeof(JsonVersionedPropertyName)));
JObject jo = JObject.Load(reader);
foreach (JProperty jp in jo.Properties())
{
foreach (var versProp in versionedProps)
{
var attrs = versProp.GetCustomAttributes(true);
foreach (var att in attrs)
{
var versionedProp = att as JsonVersionedPropertyName;
if (versionedProp != null)
{
var versions = versionedProp.VersionedNames;
PropertyInfo prop = props.FirstOrDefault(pi =>
pi.CanWrite && (string.Equals(pi.Name, jp.Name, StringComparison.OrdinalIgnoreCase) || versions.Contains(jp.Name)));
if (prop != null)
prop.SetValue(instance, jp.Value.ToObject(prop.PropertyType, serializer));
}
}
}
}
return instance;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
但是,当我尝试将此转换器与一起使用时,我的整个反序列化失败。我试图找出是否有更好的方法(版本号属性名称)代替上面的方法。
答案 0 :(得分:1)
您已经关闭。像这样的作品。我将其作为练习归纳为:):
public class OninaigConverter : JsonConverter
{
private readonly Dictionary<string, string> _propertyMappings = new Dictionary<string, string>
{
{"BillingStreetA", "BillingStreet"},
{"BillingStreet1", "BillingStreet"}
};
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
{
return objectType.GetTypeInfo().IsClass;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
object instance = Activator.CreateInstance(objectType);
var props = objectType.GetTypeInfo().DeclaredProperties.ToList();
JObject jo = JObject.Load(reader);
foreach (JProperty jp in jo.Properties())
{
if (!_propertyMappings.TryGetValue(jp.Name, out var name))
name = jp.Name;
PropertyInfo prop = props.FirstOrDefault(pi =>
pi.CanWrite && pi.GetCustomAttribute<JsonPropertyAttribute>().PropertyName == name);
prop?.SetValue(instance, jp.Value.ToObject(prop.PropertyType, serializer));
}
return instance;
}
}