【问题标题】:Can I read a JSON property with varying names into a specific property on my class with JSON.Net?我可以使用 JSON.Net 将具有不同名称的 JSON 属性读取到我的类上的特定属性中吗?
【发布时间】:2015-08-18 23:24:15
【问题描述】:

我有一个烦人的难题,我从 API 返回了多种类型,它们之间的唯一区别是属性名称。一种类型的 int 为 Count,另一种类型的 int 为 Customers,另一种类型的 int 为 Replies

类示例:

public class DateAndCount
{
    public DateTime? Date { get; set; }
    public int Count { get; set; }
}

public class DateAndCount
{
    public DateTime? Date { get; set; }
    public int Customers { get; set; }
}

public class DateAndCount
{
    public DateTime? Date { get; set; }
    public int Replies { get; set; }
}

JSON 示例:

{
  "count": 40,
  "date": "2014-01-01T00:00:00Z"
},

{
  "customers": 40,
  "date": "2014-01-01T00:00:00Z"
},

{
  "replies": 40,
  "date": "2014-01-01T00:00:00Z"
},

不必创建 3+ 个几乎相同的类,我可以让序列化程序将任何属性名称反序列化到 Count 属性中吗?

【问题讨论】:

  • 唯一想到的就是代码异味:您可以使用JsonExtensionData,这意味着整理customerscountdate json 属性/值变成Dictionary<string, object>。不知道你是否想那样做。
  • 我同意,这有点臭。这里有另一条评论建议我能做的最好的事情是拥有一个包含数据的类,并从该类继承用于 int。我没有领先并做到了。

标签: c# json json.net json-deserialization


【解决方案1】:

你可以创建一个简单的JsonConverter 来处理这个问题:

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        DateAndCount dac = new DateAndCount();
        dac.Date = (DateTime?)jo["Date"];
        // put the value of the first integer property from the JSON into Count
        dac.Count = (int)jo.Properties().First(p => p.Value.Type == JTokenType.Integer).Value;
        return dac;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

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

要使用它,请使用 [JsonConverter] 属性装饰您的 DateAndCount 类,以将转换器绑定到您的类,并像往常一样反序列化。这是一个演示:

class Program
{
    static void Main(string[] args)
    {
        ParseAndDump(@"{ ""Date"" : ""2015-08-22T19:02:42Z"", ""Count"" : 40 }");
        ParseAndDump(@"{ ""Date"" : ""2015-08-20T15:55:04Z"", ""Customers"" : 26 }");
        ParseAndDump(@"{ ""Date"" : ""2015-08-21T10:17:31Z"", ""Replies"" : 35 }");
    }

    private static void ParseAndDump(string json)
    {
        DateAndCount dac = JsonConvert.DeserializeObject<DateAndCount>(json);
        Console.WriteLine("Date: " + dac.Date);
        Console.WriteLine("Count: " + dac.Count);
        Console.WriteLine();
    }
}

[JsonConverter(typeof(DateAndCountConverter))]
class DateAndCount
{
    public DateTime? Date { get; set; }
    public int Count { get; set; }
}

输出:

Date: 8/22/2015 7:02:42 PM
Count: 40

Date: 8/20/2015 3:55:04 PM
Count: 26

Date: 8/21/2015 10:17:31 AM
Count: 35

【讨论】:

    猜你喜欢
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 2016-04-04
    • 1970-01-01
    相关资源
    最近更新 更多