使用Json.NET反序列化字符串和对象的混合集合

y1aodyip  于 2023-03-31  发布在  .NET
关注(0)|答案(2)|浏览(98)

我正在开发一个解析Minecraft JSON文件的库,但是它们的格式有点奇怪,我不知道如何用Newtonsoft的www.example.com来解析JSON.net:

{
    "values": [
        "some_object",
        "another_object",
        {
            "name": "third_object",
            "required": false
        }
    ]
}

我尝试将values数组反序列化为如下所示的类:

class TagValue
{
    public string Name;
    public bool Required = false;
}

因此,对于只是一个字符串的值,它应该将Name设置为字符串,并将Required保留为false。
我对这个库很陌生,除了最基本的反序列化之外,我不知道如何做任何更高级的事情。

j2cgzkjk

j2cgzkjk1#

试试这个

[JsonConverter(typeof(TagValueConverter))]
class TagValue
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("required")]
    public bool Required { get; set; }

    private class TagValueConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(string) ||
                objectType == typeof(TagValue);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.String)
                return new TagValue
                {
                    Name = reader.Value as string
                };
            else
            {
                var jobj = JObject.Load(reader);
                var obj = new TagValue();
                serializer.Populate(jobj.CreateReader(), obj);
                return obj;
            }
        }

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

然后假设你有/需要一个外部对象的类:

class TagValues
{
    [JsonProperty("values")]
    public TagValue[] Values { get; set; }

    public static void TestMe()
    {
        string json = @"{
            ""values"": [
                ""some_object"",
                ""another_object"",
                {
                    ""name"": ""third_object"",
                    ""required"": true
                }
            ]
        }";

        var tags = JsonConvert.DeserializeObject<TagValues>(json);

        Debug.Assert(tags.Values?.Length == 3);
        Debug.Assert(tags.Values[0].Name == "some_object");
        Debug.Assert(tags.Values[1].Name == "another_object");
        Debug.Assert(tags.Values[2].Name == "third_object" &&
                    tags.Values[2].Required == true);
    }
}

PS -您还应该按照注解中的建议使这些字段具有属性。

lp0sw83n

lp0sw83n2#

你不需要任何转换器,只要一串代码就足够了

List<TagValue> values = JObject.Parse(json)["values"]
                .Select(va => va.Type == JTokenType.Object
                ? va.ToObject<TagValue>()
                : new TagValue { Name = (string) va }
                ).ToList();

相关问题