繁体   English   中英

JSON.Net - 如何反序列化自定义类型的嵌套字段

[英]JSON.Net - How to deserialize a nested field of a custom type

我一直无法找到有关我的特定案例的问题:

我需要反序列化以下 JSON:

{ 
    "name": "My Farm",
    "barns": [
        {
            "name"": "Barn A"",
            "animalTypes": [
                "Cow",
                "Goat"
            ]
        }
    ]
}

到以下代码 model:

public class Farm
{
    public string name;
    public Barn[] barns;
}

public class Barn
{
    public string name;
    public AnimalType[] animalTypes;
}

public class AnimalType
{
    public int typeID;
}

问题:我需要将 JSON 字符串(描述动物物种名称)反序列化为包含“类型 ID”int 的“AnimalType”object。 这个要求不是我能改变的。

要获取动物的 integer 类型 ID,我可以访问外部提供的“AnimalTypeResolver”class,如下所示:

public class AnimalTypeResolver
{
    public int GetAnimalType(string animalTypeName)
    {
        // queries a map to return the right ID.
    }
}

我可以查询该解析器以获取我需要为每种动物类型存储的 int 值。

因此,我尝试为 AnimalType 编写自定义 JSONConverter:

public class AnimalTypeConverter : JsonConverter<AnimalType>
{
    public AnimalTypeResolver animalTypeResolver;

    public AnimalTypeConverter(AnimalTypeResolver animalTypeResolver)
    {
        this.animalTypeResolver = animalTypeResolver;
    }

    public override bool CanWrite => false;

    public override AnimalType ReadJson(ref JsonReader reader, Type objectType, AnimalType existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.String)
        {
            string animalTypeName = (string)reader.Value;

            return new AnimalType
            {
                typeID = animalTypeResolver.GetAnimalType(animalTypeName)
            };
        }

        return null;
    }

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

我的反序列化代码如下所示:

string farmJSON =
@"{ 
    ""name"": ""My Farm"",
    ""barns"": [
        {
            ""name"": ""Barn A"",
            ""animalTypes"": [
                ""Cow"",
                ""Goat""
            ]
        }
    ]
}";

JsonSerializer serializer = new JsonSerializer();
serializer.Converters.Add(new AnimalTypeConverter(animalTypeResolver)); // this animalTypeResolver is supplied from elsewhere in code.

Farm farm = JsonConvert.DeserializeObject<Farm>(farmJSON);

但是我收到运行时错误:

ArgumentException:无法从 System.String 转换或转换为 AnimalType。

通过阅读类似的问题,我相信我的问题是我正在尝试反序列化自定义类型 (AnimalType[]) 的嵌套字段。 其他答案解释说 JToken.FromObject() 为每个反序列化级别创建一个新的 JsonSerializer,它没有我添加到更高级别序列化程序的 JsonConverters 的概念。

但是,出于某种原因,本网站上其他问题的答案并不完全适用于我的情况。

我如何使用我的自定义 JsonConverter 来处理数据深度嵌套的情况?

如果有人可以提供有关如何进行这项工作的建议,谢谢!

JsonConvert.DeserializeObject<Farm>(farmJSON)不使用您的 JsonSerializer 实例。 我的意思是,它怎么可能访问您在代码中创建和分配的序列化程序变量?

您有两个选择:要么使用您刚刚设置的序列化程序实例的反序列化方法来反序列化 json 数据,要么使用 JsonConvert.DeserializeObject。

或者不设置序列化程序,而是使用自定义 JsonConverter 定义一些JsonSerializerSettings并将这些设置传递给JsonConvert.DeserializeObject 方法 或者,您也可以定义 JsonConvert.DeserializeObject 的默认序列化设置,如 Newtonsoft.Json 文档中所示: https://www.newtonsoft.com/json/help/html/DefaultSettings.htm

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM