【问题标题】:Deserialize JSON to c# object raising an exception将 JSON 反序列化为引发异常的 c# 对象
【发布时间】:2019-07-21 08:49:01
【问题描述】:

能否请您帮我将以下 JSON 反序列化为 c#。

[
  {
    "detectedLanguage": {
      "language": "en",
      "score": 10.0
    },
    "translations": [
      {
        "text": "",
        "to": "da"
      },
      {
        "text": "",
        "to": "da"
      }
    ]
  }
]

我已使用以下 c# 类进行反序列化,但出现异常。

public class DetectedLanguage
{
    public string language { get; set; }
    public int score { get; set; }
}

public class Translation
{
    public string text { get; set; }
    public string to { get; set; }
}

public class RootObject
{
    public DetectedLanguage detectedLanguage { get; set; }
    public List<Translation> translations { get; set; }
}

我的反序列化代码是:

var response = client.SendAsync(request).Result;
var jsonResponse = response.Content.ReadAsStringAsync().Result;
var result = JsonConvert.DeserializeObject<RootObject>(jsonResponse);

例外

无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型 'RootObject' 因为该类型需要 JSON 对象(例如 {"name":"value"}) 正确反序列化。要修复此错误 将 JSON 更改为 JSON 对象(例如 {"name":"value"})或更改 将类型反序列化为数组或实现集合的类型 接口(例如 ICollection、IList),例如 List 可以 从 JSON 数组反序列化。也可以添加 JsonArrayAttribute 强制它从 JSON 数组反序列化的类型。小路 '', 第 1 行,位置 1。

【问题讨论】:

  • 您的 JSON 表示一个数组 - 它以 [ 开头并以 ] 结尾。您正在尝试将其反序列化为单个 RootObject。要么去掉开头和结尾的方括号,要么反序列化为List&lt;RootObject&gt;
  • @JonSkeet 我更改为 List 但我仍然收到异常“System.FormatException:'输入字符串格式不正确。' .".
  • @Simant:我无法重现。使用您的确切类和 JSON,它可以很好地解析。不知道除了somewhere 之外的任何东西,很难进一步提供帮助。 (也许那是在单独的一段代码中?)
  • var json = "[{\"detectedLanguage\":{\"language\":\"en\",\"score\":0},\"translations\":[{\"text\":\"\",\"to\":\"da\"},{\"text\":\"\",\"to\":\"da\"}]}]"; var result = JsonConvert.DeserializeObject&lt;List&lt;RootObject&gt;&gt;(json); 工作正常
  • @IvanSalo 我正在获取 json [{\"detectedLanguage\":{\"language\":\"en\",\"score\":0.0},\"translations\" :[{\"text\":\"\",\"to\":\"da\"}]}] 与你的类似。

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


【解决方案1】:

score 属性有时会保存浮点值,但在我的 c# 类中,存在导致异常的数据类型 int。在 @Ivan Salo 发表评论之前我没有注意到。将数据类型 int 更改为 float 解决了我的问题。我还使用 List 来反序列化 @Jon Skeet 在 cmets 部分中建议的 JSON。

public class DetectedLanguage
{
    public string language { get; set; }
    public float score { get; set; }
}

【讨论】:

  • 回答问题as问所需的唯一部分是使用List。为了使浮点部分相关,最好在 JSON 中显示一个示例。我会以这种方式编辑您的问题,或者删除整个问题;我认为 Q&A 组合目前没有太大价值。
【解决方案2】:

编辑为完整答案:

using Newtonsoft.Json;

class Program
{
    public partial class RootObject
    {
        [JsonProperty("detectedLanguage")]
        public DetectedLanguage DetectedLanguage { get; set; }

        [JsonProperty("translations")]
        public Translation[] Translations { get; set; }
    }

    public partial class DetectedLanguage
    {
        [JsonProperty("language")]
        public string Language { get; set; }

        [JsonProperty("score")]
        public long Score { get; set; }
    }

    public partial class Translation
    {
        [JsonProperty("text")]
        public string Text { get; set; }

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

    public partial class RootObject
    {
        public static RootObject[] FromJson(string jsonresponse) => JsonConvert.DeserializeObject<RootObject[]>(jsonresponse);
    }

    static void Main(string[] args)
    {
        var response = client.SendAsync(request).Result;
        var jsonResponse = response.Content.ReadAsStringAsync().Result;
        var result = RootObject.FromJson(jsonResponse);
        System.Console.WriteLine(result[0].DetectedLanguage.Language); //outputs "en"
    }
}

【讨论】:

  • 虽然这在更传统方面会更好,但在反序列化为正确的类型时,现有结构有效
  • 我不知道为什么这被否决了。该请求是为了帮助“将以下 JSON 反序列化为 c#。”,我的代码就是这样做的。它还包括使用 RootObject 作为数组。
  • 原始模型代码反序列化了 JSON。 唯一的 问题是它被反序列化为什么。最初的答案根本没有显示反序列化 - 现在好多了,但它没有 任何 解释的事实使它仍然对 IMO 没有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-18
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多