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

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

Barbara Streisand
Barbara Streisand原创
2025-02-02 20:46:12437浏览

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

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

问题:

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

示例JSON:

<code class="language-json">[
  {
    "email": "test1@example.com",
    "timestamp": 1337966815,
    "category": [
      "newuser",
      "transactional"
    ],
    "event": "open"
  },
  {
    "email": "test2@example.com",
    "timestamp": 1337966815,
    "category": "olduser",
    "event": "open"
  }
]</code>

解决方案:自定义JsonConverter

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

代码示例:

<code class="language-csharp">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)}");
        }
    }
}</code>

此代码定义了一个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