c# - 在 C# 中反序列化可能是整数或字符串列表的 JSON

标签 c# json json.net deserialization

我正在使用 C#反序列化 JSON 字符串的集合。每个字符串都有一个属性 employer_normalized应该包含 stringList<int> List 中的值总是积极的。在某些情况下 employer_normalized设置为 -1 , 所以我想用一些设置 employer_normalized 的行为来覆盖这些情况至 null .

这是我的类(class):

public class EmployerNormalized
{
  public string company;
  public List<int> code;
}

良好的 JSON

"employer_normalized": {
        "company": "self",
        "code": [
          "4581 ",
          "6732 ",
          "9121",
          "9999 ",
          "5947 ",
          "8322 ",
          "8351 ",
          "7335 ",
          "9999 ",
          "4225 ",
          "8399 "
        ]
      }

错误的 JSON

"employer_normalized": -1

我目前正在使用 Json.NET做我的 JSON 解析。解决这个问题的优雅解决方案是什么?最好只设置 employer_normalizednull如果是-1 ?如果可以,我该怎么做?

最佳答案

您可以使用自定义的 JsonConverter 来处理这种情况。无论您在哪里期待 EmployerNormalized ,转换器可以检查该属性的值是否为 -1并返回null,否则正常反序列化。

这是转换器的代码:

public class EmployerNormalizedConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(EmployerNormalized));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        if (token.Type == JTokenType.Object)
        {
            return token.ToObject<EmployerNormalized>();
        }
        return null;
    }

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

下面是一个展示如何使用它的演示:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""good"" : {
                ""company"": ""self"",
                ""code"": [
                    ""4581 "",
                    ""6732 "",
                    ""9121"",
                    ""9999 "",
                    ""5947 "",
                    ""8322 "",
                    ""8351 "",
                    ""7335 "",
                    ""9999 "",
                    ""4225 "",
                    ""8399 ""
                ]
            },
            ""bad"" : -1
        }";

        Wrapper wrapper =
            JsonConvert.DeserializeObject<Wrapper>(json, 
                new EmployerNormalizedConverter());

        DumpEmployer("good", wrapper.good);
        DumpEmployer("bad", wrapper.bad);
    }

    private static void DumpEmployer(string prop, EmployerNormalized emp)
    {
        Console.WriteLine(prop);
        if (emp != null)
        {
            Console.WriteLine("  company: " + emp.company);
            Console.WriteLine("  codes: " + 
                string.Join(", ", emp.code.Select(c => c.ToString())));
        }
        else
            Console.WriteLine("  (null)");
    }

    public class Wrapper
    {
        public EmployerNormalized good { get; set; }
        public EmployerNormalized bad { get; set; }
    }

    public class EmployerNormalized
    {
        public string company;
        public List<int> code;
    }
}

这是输出:

good
  company: self
  codes: 4581, 6732, 9121, 9999, 5947, 8322, 8351, 7335, 9999, 4225, 8399
bad
  (null)

重要说明:您可能想装饰 EmployerNormalized[JsonConverter(typeof(EmployerNormalizedConverter))]上课,但如果你这样做,那么转换器以其当前形式最终将递归调用自身,直到它出错并返回 StackOverflowException。 .如果您需要/想要使用该属性,那么 ReadJson 的代码转换器中的方法将需要更改,以便它手动创建 EmployerNormalized 的实例类并单独填充其所有属性,而不是调用 token.ToObject<EmployerNormalized>() .这是 ReadJson 的替代版本这将避免递归问题:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    JToken token = JToken.Load(reader);
    if (token.Type == JTokenType.Object)
    {
        EmployerNormalized employer = new EmployerNormalized();
        employer.company = token["company"].ToString();
        employer.code = token["code"].ToObject<List<int>>();
        return employer;
    }
    return null;
}

关于c# - 在 C# 中反序列化可能是整数或字符串列表的 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20547698/

相关文章:

c# - 机器人遇到错误或错误。要继续运行该机器人,请修复机器人源代码

javascript - 变量在运行时未定义,但在使用调试器时定义

javascript - 您能推荐任何在线 JSON 网格查看器或表格查看器吗?

c# - JSON.Net、JsonConvert.DeserializeObject - 反序列化问题

vb.net - JSON.Net VB 反序列化不起作用

c# - 如何将公司名称放入命名空间?

c# - UITableViewController 收到内存警告后显示为空白

c# - 如果我有对象 ID,如何使用 REST API 获取 AzureAD 中对象的显示名称?

javascript - 使用 Node 将 Google 产品分类加载到 Firestore 中

json - 如何将 json 文件中的 exif 数据写入 jpg 图像?