使用Newtonsoft

我正在尝试反序列化具有未命名数组数组的JSON对象,并且遇到了一些问题。我正在测试的代码:

var json = "{ \"Triangles\": [[1337],[1338],[1339]]}";
var mesh  = JsonConvert.DeserializeObject<Mesh>(json);

和感兴趣的类别:

public class Mesh
{
    [JsonProperty]
    public Triangle[] Triangles { get; set; }
}

public class Triangle
{
    [JsonProperty]
    public int[] Indices { get; set; }
}

运行代码并尝试使用Newtonsoft反序列化,我得到以下异常:

Newtonsoft.Json.JsonSerializationException
  HResult=0x80131500
  Message=Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ConsoleApp1.Triangle' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection,IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'triangles[0]',line 1,position 17.

将[JsonArray]添加到Triangle类中会导致以下异常:

Newtonsoft.Json.JsonSerializationException
  HResult=0x80131500
  Message=Cannot create and populate list type ConsoleApp1.Triangle. Path 'Triangles[0]',position 17.

我想念什么?

编辑:我显然忘记提及的重要一件事是,出于语义原因,我想将其反序列化为文章中列出的类。也就是说,尽管将三角形反序列化为List<List<int>>int[][]是可行的,但我还是非常希望不这样做。

xianjian3 回答:使用Newtonsoft

带有自定义转换器。将数组反序列化为JArray并从中选择。

var json = "{ \"Triangles\": [[1337,1400],[1338],[1339]]}";
var mesh = JsonConvert.DeserializeObject<Mesh>(json);

public class Mesh
{
    [JsonConverter(typeof(MyConverter))]
    public Triangle[] Triangles { get; set; }
}   
public class Triangle
{
    [JsonProperty]
    public int[] Indices { get; set; }
}

public class MyConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }
        var result =
            JArray.Load(reader)
            .Select(x =>
                new Triangle { Indices = x.Select(y => (int)y).ToArray() }
            );

        return result.ToArray();
    }

    public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
,

当前设置班级的方式。 JSON.NET将尝试将Triangle[]反序列化为json对象数组。最简单的解决方案是将Triangles的类型更改为int[,],使其成为2d数组。如果您想继续使用Triangle[],则需要使用自定义的JsonConverter

编辑:由于要保留Triangle类,因此需要一个自定义JsonConverter类。

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class TriangleJsonConverter : JsonConverter<Triangle>
{
    // Called when Triangle is written
    public override void WriteJson(JsonWriter writer,Triangle value,JsonSerializer serializer)
    {
        // Uses JsonSerializer to write the int[] to the JsonWriter
        serializer.Serialize(writer,value.Indices);
    }

    // Called when Triangle is read
    public override Triangle ReadJson(JsonReader reader,Triangle existingValue,bool hasExistingValue,JsonSerializer serializer)
    {
        // Reads a json array (JArray) from the JsonReader
        var array = JArray.Load(reader);
        // Creates a new Triangle.
        return new Triangle
        {
            // converts the json array to an int[]
            Indices = array.ToObject<int[]>()
        };
    }
}

要告诉JSON.NET使用TriangleJsonConverter,您需要将JaonArray应用于Triangles字段而不是JsonProperty

public class Mesh
{
    [JsonArray(ItemConverterType = typeof(TriangleJsonConverter))]
    public Triangle[] Triangles { get; set; }
}
本文链接:https://www.f2er.com/3167755.html

大家都在问