【问题标题】:Trouble deserializing JSON (got value array when single value expected)反序列化 JSON 时遇到问题(预期单个值时得到值数组)
【发布时间】:2019-05-30 10:55:25
【问题描述】:

我正在从图形数据库中读取数据并将响应作为动态对象获取。我检查结果并尝试将它们反序列化:

var e = results.GetEnumerator();

while (e.MoveNext())
{
    var serialized = JsonConvert.SerializeObject(e.Current);
    // {"FlagCalculateclientside":[false],"Description":["Some detailed info"], "Name": ["MyDetailedEntity"]}
    var val = JsonConvert.DeserializeObject<MyObject>(serialized);
}

public class MyObject
{
    public bool FlagCalculateclientside { get; set; }
    public string Description { get; set; }
    public string Name { get; set; }
}

但我收到以下错误:

Newtonsoft.Json.JsonReaderException:解析值时遇到意外字符:[。路径“FlagCalculateclientside”,第 1 行,位置 28。 在 Newtonsoft.Json.JsonTextReader.ReadAsBoolean() 在 Newtonsoft.Json.JsonReader.ReadForType(JsonContract 合同,布尔 hasConverter) ...

我猜这是因为值在数组中,但每个键只有一个值。

知道如何解决这个问题吗?

【问题讨论】:

  • 有问题的注释代码是您的 json 响应吗?
  • 结果从何而来?数据/对象设置如何?
  • @A.M. Patel 是的,这是“序列化”的值
  • @Tony Abrams 我向 Gremlin 客户端发出请求,如下所示:var results = await gremlinClient.SubmitAsync&lt;dynamic&gt;(requestScript).ConfigureAwait(false); requestScript 只保存我的 Gremlin 查询字符串
  • Gremlin 查询是什么样的?

标签: c# json.net deserialization


【解决方案1】:

您的模型与您的 JSON 不匹配,所有属性都是数组,换句话说,它们被 [...] 包围。要修复,请将模型更改为:

public class MyObject
{
    public List<bool> FlagCalculateclientside { get; set; }
    public List<string> Description { get; set; }
    public List<string> Name { get; set; }
}

另一种方法是使用自定义转换器,例如:

public class ArrayConverter<T> : JsonConverter<T>
{
    public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);

        //This isn't the best code but shows you what you need to do.
        return token.ToObject<List<T>>().First();
    }

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

并将您的模型更改为:

public class MyObject
{
    [JsonConverter(typeof(ArrayConverter<bool>))]
    public bool FlagCalculateclientside { get; set; }

    [JsonConverter(typeof(ArrayConverter<string>))]
    public string Description { get; set; }

    [JsonConverter(typeof(ArrayConverter<string>))]
    public string Name { get; set; }
}

【讨论】:

  • 虽然这确实“解决”了问题,但让模型具有数组是没有意义的——因为 OP 声明他们只期望模型中的每个字段有一个值。
  • @TonyAbrams OP 询问如何解决这个问题,这就是问题所在。另一种方法是修复 Gremlin 查询,但这非常复杂。通常,Gremlin 将属性值作为数组提供给您。
  • 感谢您的回答。我希望能够将每个数组中的第一个属性映射到我的模型中的属性。这些数组中的元素永远不会超过一个,只是响应是这样的......
  • @kanpeki 这意味着您需要更改您的查询,这是一个完全不同的问题。
  • @DavidG 我对此不是很熟悉,但是有没有办法制作自定义反序列化器?
猜你喜欢
  • 2020-10-20
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 2021-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多