Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 序列化后Json.Net属性名称已更改_C#_Json_Json.net - Fatal编程技术网

C# 序列化后Json.Net属性名称已更改

C# 序列化后Json.Net属性名称已更改,c#,json,json.net,C#,Json,Json.net,假设我有一个以前用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; } } 然而,我不得不返回并将Bill

假设我有一个以前用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
更改为
BillingStreet 1
,然后再次更改为
BillingStreet
。我试图在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();
    }
}

但是,当我尝试将此转换器与另一个转换器一起使用时,我的整个反序列化失败。我正在试图找出是否有更好的方法(版本化的属性名)来代替上面的方法。

你很接近了。像这样的东西很管用。我将把它作为一个练习来泛化:):

公共类oninagconverter:JsonConverter
{
private readonly Dictionary\u propertyMappings=新字典
{
{“BillingStreetA”,“BillingStreet”},
{“BillingStreet1”,“BillingStreet”}
};
公共覆盖boolcanwrite=>false;
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
公共覆盖布尔CanConvert(类型objectType)
{
返回objectType.GetTypeInfo().IsClass;
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
对象实例=Activator.CreateInstance(objectType);
var props=objectType.GetTypeInfo().DeclaredProperties.ToList();
JObject jo=JObject.Load(读卡器);
foreach(jo.property()中的JProperty jp)
{
if(!\u propertyMappings.TryGetValue(jp.Name,out var Name))
name=jp.name;
PropertyInfo prop=props.FirstOrDefault(pi=>
pi.CanWrite&&pi.GetCustomAttribute().PropertyName==name);
prop?.SetValue(实例,jp.Value.ToObject(prop.PropertyType,序列化程序));
}
返回实例;
}
}
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;
    }
}