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

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

问题描述:

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

E.G.用:

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

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

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方法的参数。

+0

看起来像是我试着去做 - 但我会建议最终,你最终会使用标准的JSON。每个'人'必须重复字段名称,但价格很低。 – Patrick

你可以用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 }); 
    } 
} 

然后,你可以把它应用到你的类:

[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); 
+0

这似乎是在正确的轨道上,但它似乎只处理一个Person数组,而不是Person数组数组。我将标记为确认JsonConverter可以做到的答案。看到我的答案,我想出了实现。如果您发现任何问题,请告诉我。 – xr280xr

public override bool CanConvert(Type objectType) 
    { 
     if (objectType == typeof(List<Person>)) return true; 

     return false; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     List<Person> persons = new List<Person>(); 

     JArray personsArray = (JArray)serializer.Deserialize(reader); 

     foreach (var personArray in personsArray.Children<JArray>()) 
     { 
      persons.Add(new Person() { 
         First = personArray[0].Value<string>(), 
         Last = personArray[1].Value<string>(), 
         Age = personArray[2].Value<string>() 
         }); 
     } 

     return persons; 
    }