首页 > 后端开发 > C++ > 如何处理同一属性的单个项目或数组的JSON.NET?

如何处理同一属性的单个项目或数组的JSON.NET?

Barbara Streisand
发布: 2025-02-02 20:46:12
原创
528 人浏览过

处理JSON.NET中相同属性的单个项目或数组

本文探讨如何使用JSON.NET处理API返回的JSON数据中,属性值既可能是单个字符串,也可能是字符串数组的情况。 以SendGrid事件API为例,其categories属性可能为单个字符串或字符串数组。

问题:

SendGrid事件API返回的JSON数据中,categories属性的格式不一致,可能是单个字符串,也可能是字符串数组,这给反序列化带来了挑战。

示例JSON:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

[

  {

    "email": "test1@example.com",

    "timestamp": 1337966815,

    "category": [

      "newuser",

      "transactional"

    ],

    "event": "open"

  },

  {

    "email": "test2@example.com",

    "timestamp": 1337966815,

    "category": "olduser",

    "event": "open"

  }

]

登录后复制

解决方案:自定义JsonConverter

为了优雅地解决这个问题,最佳方案是创建一个自定义的JsonConverter。 该转换器能够识别categories属性的值类型,并将其正确反序列化为List<string>

代码示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

using Newtonsoft.Json;

using Newtonsoft.Json.Linq;

using System;

using System.Collections.Generic;

 

public class Item

{

    [JsonProperty("email")]

    public string Email { get; set; }

 

    [JsonProperty("timestamp")]

    public int Timestamp { get; set; }

 

    [JsonProperty("event")]

    public string Event { get; set; }

 

    [JsonProperty("category")]

    [JsonConverter(typeof(SingleOrArrayConverter<string>))]

    public List<string> Categories { get; set; }

}

 

public class SingleOrArrayConverter<T> : JsonConverter

{

    public override bool CanConvert(Type objectType)

    {

        return objectType == typeof(List<T>);

    }

 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)

    {

        JToken token = JToken.Load(reader);

        if (token.Type == JTokenType.Array)

        {

            return token.ToObject<List<T>>();

        }

        if (token.Type == JTokenType.Null)

        {

            return null;

        }

        return new List<T> { token.ToObject<T>() };

    }

 

    public override bool CanWrite => false; // 只支持反序列化

 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)

    {

        throw new NotImplementedException();

    }

}

 

public class Example

{

    public static void Main(string[] args)

    {

        string json = @"

        [

          {

            ""email"": ""test1@example.com"",

            ""timestamp"": 1337966815,

            ""category"": [

              ""newuser"",

              ""transactional""

            ],

            ""event"": ""open""

          },

          {

            ""email"": ""test2@example.com"",

            ""timestamp"": 1337966815,

            ""category"": ""olduser"",

            ""event"": ""open""

          }

        ]";

 

        List<Item> items = JsonConvert.DeserializeObject<List<Item>>(json);

 

        foreach (var item in items)

        {

            Console.WriteLine($"Email: {item.Email}, Timestamp: {item.Timestamp}, Event: {item.Event}, Categories: {string.Join(", ", item.Categories)}");

        }

    }

}

登录后复制

此代码定义了一个Item类和一个泛型SingleOrArrayConverterSingleOrArrayConverter能够处理单个值和数组,并将其转换为List<string>。 主程序演示了如何使用该转换器反序列化JSON数据。 注意,此转换器只支持反序列化(CanWrite => false)。

How can I handle JSON.net deserialization of a single item or array for the same property?

以上是如何处理同一属性的单个项目或数组的JSON.NET?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板