【问题标题】:"Unexpected character encountered while parsing value: [." exception when deserializing into a List<string> field“解析值时遇到意外字符:[。”反序列化为 List<string> 字段时出现异常
【发布时间】:2020-11-20 11:09:05
【问题描述】:

我有一个对象:

class Node
{
  public Node(string text)
  {
    Text = new List<string> { text };
  }

  public List<string> Text { get; set; }
}

当我尝试使用 Json.NET 将该对象的实例往返传输到 JSON 时:

var root = new Node("");

var json = JsonConvert.SerializeObject(root);
root = JsonConvert.DeserializeObject<Node>(json);

我收到以下错误:

Unhandled Exception: Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: [. Path 'Text', line 2, position 11.
   at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType)
   at Newtonsoft.Json.JsonTextReader.ReadAsString()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)

由于某种原因,它无法处理 List&lt;string&gt; Text 字段,我终其一生都无法弄清楚。

我实际上是在尝试反序列化它刚刚序列化的字符串。我可以尝试编写一个自定义转换器,但这里似乎没有必要。

也许我可以使用一个属性来帮助它?

编辑:

创建了一个新的(.NET Framework 控制台应用程序)项目,其中只有一个 Program.cs 文件,其中包含以下代码:

using Newtonsoft.Json; // Version: 12.0.3
using System.Collections.Generic;

namespace ConsoleApp1
{
  class Node
  {
    public Node(string text)
    {
      Text = new List<string> { text };
    }

    public List<string> Text { get; set; }
  }

  class Program
  {
    static void Main()
    {
      var root = new Node("");

      var json = JsonConvert.SerializeObject(root);
      root = JsonConvert.DeserializeObject<Node>(json);
    }
  }
}

我仍然遇到同样的错误。

【问题讨论】:

    标签: c# json json.net jsonconvert


    【解决方案1】:

    您的问题是您的Node 类没有无参数构造函数。相反,它有一个参数化的构造函数。在这种情况下,Json.NET 将调用参数化构造函数,通过大小写不变的名称将构造函数参数与 JSON 属性匹配。不幸的是,构造函数的参数text 与属性Text 的类型不匹配。具体来说,参数是单个string,而属性是字符串数组:

    class Node
    {
        public Node(string text /* A single string named text */)
        {
            Text = new List<string> { text };
        }
    
        public List<string> Text { get; set; } // A collection of strings named Text
    }
    

    由于 JSON 中的字符串数组无法反序列化为构造类所需的单个字符串,因此您会看到您看到的异常。演示小提琴 #1 here.

    要解决此问题,您的选择包括:

    1. 添加无参数构造函数。 Json.NET 默认会调用它:

      class Node
      {
          public Node() => Text = new List<string>();
      
          public Node(string text /* A single string named text */)
          {
              Text = new List<string> { text };
          }
      
          public List<string> Text { get; set; } // A collection of strings named Text
      }
      

      如果您用[JsonConstructor] 标记它,它可能是私有的或受保护的。

      演示小提琴 #2 here.

    2. 更改构造函数以接受字符串集合。 params string [] text 似乎是最简单的:

      class Node
      {
          public Node(params string [] text)
          {
              Text = text.ToList();
          }
      
          public List<string> Text { get; set; } // A collection of strings named Text
      }
      

      演示小提琴#3 here.

    3. 将构造函数中的 text 参数重命名为不同的名称,例如 singletext,并不理想,因为 Json.NET 将传递 null 以获取缺少的构造函数值,该值最初将添加到 Text集合并将保留在那里,除非在反序列化期间随后替换集合。

      演示小提琴 #4 here.

    相关阅读:

    【讨论】:

      【解决方案2】:

      所以我通过将字段从Text重命名为DialogueText来解决问题,将其重命名为Texts也解决了它。

      由于我已经尝试通过 JsonProperty 设置名称,但没有成功,我目前的假设是,Text 可能是一个保留字段名称,它被硬编码为期待 string

      【讨论】:

        猜你喜欢
        • 2023-03-05
        • 2014-06-21
        • 2014-06-09
        • 2016-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-30
        • 1970-01-01
        相关资源
        最近更新 更多