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

无法将 Jobject 类型转换为 Dictionary<string, EntityProperty>

如何解决无法将 Jobject 类型转换为 Dictionary<string, EntityProperty>

如何将 JObject 转换为 Dictionary<string,EntityProperty>。 我试过这种方式

data.ToObject<Dictionary<string,EntityProperty>>()

但它给我错误“”将值“123”转换为“Microsoft.Azure.Cosmos.Table.EntityProperty”的错误。路径“版本”。"}"

我该怎么做? 调试中的数据给了我这个结构:

{
  "Version": "123","Eest": {
    "Bulls": 1848,"Message": "Passed (0.325 mA < 2[0] => 'P')","Credit": 0.325,"Read": 0.14,"SBin": "P"
  },"GenericTests": [],"HostVersion": "Test","RawSampleIDData": [
    1,3,2,4
  ]
}

解决方法

即使使用 custom JsonConverter,您也无法将问题中显示的 JSON 对象反序列化为 Dictionary<string,EntityProperty>这是因为 EntityProperty 是一个 Class用于在表中存储有关实体中单个属性的信息。因此,它可以捕获各种 .Net 原语 including

  • byte []
  • bool
  • DateTime
  • doubleintlong
  • string

但是,您的根 JSON 对象的值包括嵌套数组 ("RawSampleIDData") 和对象 ("Eest")。因此,它不能反序列化为 EntityProperty 原语字典。您将需要采用不同的数据模型来反序列化该 JSON。

相关见:

如果您的对象值完全是 JSON 原语,您可以引入以下转换器:

public class EntityPropertyConverter : JsonConverter<EntityProperty>
{
    public override void WriteJson(JsonWriter writer,EntityProperty value,JsonSerializer serializer) =>
        serializer.Serialize(writer,value.PropertyAsObject);

    public override EntityProperty ReadJson(JsonReader reader,Type objectType,EntityProperty existingValue,bool hasExistingValue,JsonSerializer serializer)
    {
        switch (reader.MoveToContentAndAssert().TokenType)
        {
            case JsonToken.Null:
                return null;
            case JsonToken.Integer:
                if (reader.Value is int i)
                    return new EntityProperty(i);
                else if (reader.Value is long l)
                    return new EntityProperty(l);
                // BigInteger not supported.
                break;
            case JsonToken.Float:
                if (reader.Value is double d)
                    return new EntityProperty(d);
                else if (reader.Value is decimal m)
                    return new EntityProperty((double)m);
                break;
            case JsonToken.String:
                return new EntityProperty((string)reader.Value);
            case JsonToken.Boolean:
                return new EntityProperty((bool)reader.Value);
            case JsonToken.Date:
                if (reader.Value is DateTime dt)
                    return new EntityProperty(dt);
                else if (reader.Value is DateTimeOffset dto)
                    return new EntityProperty(dto);
                break;
            case JsonToken.Bytes:
                if (reader.Value is byte [] a)
                    return new EntityProperty(a);
                else if (reader.Value is Guid g)
                    return new EntityProperty(g);
                break;
        }
        throw new JsonSerializationException(string.Format("Cannot convert value {0} to {1}",reader.TokenType,nameof(EntityProperty)));
    }       
}

public static partial class JsonExtensions
{
    public static JsonReader MoveToContentAndAssert(this JsonReader reader)
    {
        if (reader == null)
            throw new ArgumentNullException();
        if (reader.TokenType == JsonToken.None)       // Skip past beginning of stream.
            reader.ReadAndAssert();
        while (reader.TokenType == JsonToken.Comment) // Skip past comments.
            reader.ReadAndAssert();
        return reader;
    }

    public static JsonReader ReadAndAssert(this JsonReader reader)
    {
        if (reader == null)
            throw new ArgumentNullException();
        if (!reader.Read())
            throw new JsonReaderException("Unexpected end of JSON stream.");
        return reader;
    }
}

然后做:

var settings = new JsonSerializerSettings
{
    Converters = { new EntityPropertyConverter() },};
var dict = data.ToObject<Dictionary<string,EntityProperty>>(JsonSerializer.CreateDefault(settings));

演示小提琴here

更新

使用上述转换器,将任意 JObject 反序列化为 Dictionary<string,EntityProperty> 的一种选择是将对象展平为由每个原始值的 path 键控的字典,如下所示:

var settings = new JsonSerializerSettings
{
    Converters = { new EntityPropertyConverter() },};
var serializer = JsonSerializer.CreateDefault(settings);
var dict = data.Descendants().OfType<JValue>().ToDictionary(v => v.Path,v => v.ToObject<EntityProperty>(serializer));

对于问题中的 JSON,结果是

{
  "Version": "123","Eest.Bulls": 1848,"Eest.Message": "Passed (0.325 mA < 2[0] => 'P')","Eest.Credit": 0.325,"Eest.Read": 0.14,"Eest.SBin": "P","HostVersion": "Test","RawSampleIDData[0]": 1,"RawSampleIDData[1]": 3,"RawSampleIDData[2]": 2,"RawSampleIDData[3]": 4
}

演示小提琴 #2 here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 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”。这是什么意思?