JSON 反序列化 - 使用 JSON.NET 将数组索引映射到属性 [英] JSON deserialization - Map array indices to properties with JSON.NET

查看:39
本文介绍了JSON 反序列化 - 使用 JSON.NET 将数组索引映射到属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

E.G.与:

<预><代码>[[约翰"、史密斯"、23"]、[宝拉"、马丁"、54"]

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

public class Person {公共字符串第一个{get;set;}公共字符串 Last {get;set;}公共字符串年龄{get;set;}}

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

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

具体来说,我不确定 JsonConverter 是否适合使用,而且我无法弄清楚如何实现 CanConvert 以及如何使用传递给的参数ReadJson 方法.

解决方案

您可以使用 JsonConverter.一个用于此目的的简单转换器是:

公共类 PersonConverter : JsonConverter{public override bool CanConvert(Type objectType){返回 objectType == typeof(Person);}公共覆盖对象 ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer){if (reader.TokenType == JsonToken.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);归还人;}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(JsonSerializer) 将它们反序列化为所需的类型:

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

然后你可以把它应用到你的班级:

[JsonConverter(typeof(PersonConverter))]公开课人{公共字符串第一个{得到;放;}公共字符串 Last { get;放;}公共字符串年龄{得到;放;}}

或者在设置中使用:

var settings = new JsonSerializerSettings { Converters = new [] { new PersonConverter() } };var list = JsonConvert.DeserializeObject>(json, settings);

I want to deserialize a 2-dimensional array to a collection of .net objects. The reason is, array syntax will be easier for my user to work with in an input file. So I just want to map the indices of the arrays to specific properties of my target type.

E.G. With:

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

I would get two instances of a Person:

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

where index 0 of an inner array maps to First, index 1 maps to Last, and index 2 maps to Age;

Is there a way to extend Json.NET so that I can do the mapping during deserialization so the implementation details are hidden? I have been playing around with a custom JsonConverter but I haven't found much info on how to use it.

Edit: Specifically, I'm not sure if JsonConverter is the right thing to use, and I'm having trouble figuring out how to implement CanConvert and how to use the parameters passed to the ReadJson method.

解决方案

You can do this with a JsonConverter. A simple converter for this purpose would be:

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 });
    }
}

If the specific properties have non-primitive types, you can use JToken.ToObject<T>(JsonSerializer) to deserialize them to the required type:

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

Then you can apply it to your class:

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

Or use it in settings:

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

这篇关于JSON 反序列化 - 使用 JSON.NET 将数组索引映射到属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆