微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

反序列化 JSON,其中属性名称指示值的类型

如何解决反序列化 JSON,其中属性名称指示值的类型

我目前正在处理从外部 API 获取数据的问题。我收到的数据如下所示。 (只是一个模型;不要指望这些值有任何意义。这只是为了说明我得到的数据类型。)

{
   "user": [
      {
        "key": "12345678","data": [
          {
            "id": "Name","string": "Bob"
          },{
            "id": "elapsedtimeSinceLastMessage","timestamp": 1618233964000
          },{
            "id": "Age","number": 27
          }
        ]
      }
   ]
}

我真的不知道我应该如何反序列化这个 JSON。

我现在用来反序列化的类如下所示:

public class User
{
    [JsonProperty("key")]
    public string Key { get; set; }

    [JsonProperty("data")]
    public List<DataEntry> DataEntries { get; set; }
}

public class DataEntry
{
    [JsonProperty("id")]
    public string Id { get; set; }

    public Type Value { get; set; }
}

而且我不知道我需要设置什么才能反序列化 Value 中的 DataEntry。也许有人可以引导我走向正确的方向?

解决方法

一个攻击角度是字典:

Check {1,2,3},odd_len? true
Check {4,5},odd_len? false
Check {6,7,8},odd_len? true
Processing {1,3,6,8}
After process: a:{1,4,9} b:{4,5} c:{36,49,64}

提取有点痛苦但可能:

public class WithUser
{
    public List<User> User { get; set; }

}

public class User
{
    [JsonProperty("key")]
    public string Key { get; set; }

    [JsonProperty("data")]
    public List<Dictionary<string,object>> DataEntries { get; set; }
}
,

此 JSON 的 Data 部分实际上只是伪装的 Dictionary<string,object>。您可以使用自定义 JsonConverter 将 ID/值对列表转换为易于使用的格式。

首先,定义这些类:

class RootObject
{
    [JsonProperty("user")]
    public List<User> Users { get; set; }
}

class User
{
    public string Key { get; set; }

    [JsonConverter(typeof(CustomDataConverter))]
    public Dictionary<string,object> Data { get; set; }
}

接下来,定义转换器:

class CustomDataConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Dictionary<string,object>);
    }

    public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
    {
        return JToken.Load(reader)
            .Children<JObject>()
            .ToDictionary(jo => (string)jo["id"],jo => jo.Properties()
                                  .Where(jp => jp.Name != "id" && jp.Value is JValue)
                                  .Select(jp => ((JValue)jp.Value).Value)
                                  .FirstOrDefault());
    }

    public override bool CanWrite => false;

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

然后您可以像这样反序列化和转储数据:

var root = JsonConvert.DeserializeObject<RootObject>(json);
foreach (User user in root.Users)
{
    Console.WriteLine("User Key: " + user.Key);
    foreach (var kvp in user.Data)
    {
        Console.WriteLine(kvp.Key + ": " + kvp.Value);
    }
}

这是一个工作演示:https://dotnetfiddle.net/GIT4dl

,

主要问题在于您创建的模型。

首先,基于 JSON,您需要另一个包含用户列表的类。

public class ResultClass
{
    public List<User> User { get; set; }
}

之后,因为data属性的第二个对象没有常量名,我们不能为其指定一个常量名(比如value)。我们应该将数据属性定义为一个对象。所以用户类应该是这样的:

public class User
{
    [JsonProperty("key")]
    public string Key { get; set; }

    [JsonProperty("data")]
    public List<object> DataEntries { get; set; }
}

最后,在控制器中,您应该反序列化 ResultJson 类:

var result = JsonConvert.DeserializeObject<ResultClass>(jsonTxt);
,

您可以使用 Json to C#。它从您的 json 字符串生成以下类。如您所见,您还可以使用可为空类型(long?,int?)。如果有值,则设置所需的变量。否则将其保留为空。这样,您就可以根据数据的 id 获取不同的类型。

public class DataEntry
{
    [JsonProperty("id")]
    public string Id { get; set; }

    [JsonProperty("string")]
    public string String { get; set; }

    [JsonProperty("timestamp")]
    public long? Timestamp { get; set; }

    [JsonProperty("number")]
    public int? Number { get; set; }
}

public class User
{
    [JsonProperty("key")]
    public string Key { get; set; }

    [JsonProperty("data")]
    public List<DataEntry> Data { get; set; }
}

public class Root
{
    public List<User> User { get; set; }
}

反序列化:

string response = "{\"user\":[{\"key\":\"12345678\",\"data\":[{\"id\":\"Name\",\"string\":\"Bob\"},{\"id\":\"ElapsedTimeSinceLastMessage\",\"timestamp\":1618233964000},{\"id\":\"Age\",\"number\":27}]}]}";
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(response);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?