一尘不染

JSON反序列化-使用JSON.NET将数组索引映射到属性

json

我想将二维数组反序列化为.net对象的集合。原因是,数组语法将使我的用户更容易在输入文件中使用。所以我只想将数组的索引映射到目标类型的特定属性。

EG具有:

[
     ["John", "Smith", "23"],
     ["Paula", "Martin", "54]
]

我会得到一个Person的两个实例:

public class Person {
    public string First {get;set;}
    public string Last {get;set;}
    public string Age {get;set;}
}

其中内部数组的索引0映射到First,索引1映射到Last,索引2映射到Age;

有没有一种扩展Json.NET的方法,以便我可以在反序列化期间进行映射,从而隐藏实现细节?我一直在玩一个自定义,JsonConverter但是我没有找到太多关于如何使用它的信息。

编辑:具体来说,我不确定是否JsonConverter使用正确的东西,而且在弄清楚如何实现CanConvert以及如何使用传递给ReadJson方法的参数时遇到麻烦。


阅读 229

收藏
2020-07-27

共1个答案

一尘不染

您可以使用JsonConverter。为此目的,一个简单的转换器将是:

public class PersonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Person);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var array = JArray.Load(reader);
        var person = (existingValue as Person ?? new Person());
        person.First = (string)array.ElementAtOrDefault(0);
        person.Last = (string)array.ElementAtOrDefault(1);
        person.Age = (string)array.ElementAtOrDefault(2);
        return person;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var person = (Person)value;
        serializer.Serialize(writer, new[] { person.First, person.Last, person.Age });
    }
}

如果特定属性具有非基本类型,则可以用于JToken.ToObject<T>(JsonSerializer)将它们反序列化为所需的类型:

person.First = array.ElementAtOrDefault(0)?.ToObject<string>(serializer);

然后,您可以将其应用于您的班级:

[JsonConverter(typeof(PersonConverter))]
public class Person
{
    public string First { get; set; }
    public string Last { get; set; }
    public string Age { get; set; }
}

或在设置中使用它:

var settings = new JsonSerializerSettings { Converters = new [] { new PersonConverter() } };
var list = JsonConvert.DeserializeObject<List<Person>>(json, settings);
2020-07-27