c# - “解析值时遇到意外字符:[。” 反序列化为列表时出现异常场地
问题描述
我有一个对象:
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<string> 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);
}
}
}
我仍然遇到同样的错误。
解决方案
您的问题是您的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在这里。
为了解决这个问题,您的选择包括:
添加无参数构造函数。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在这里。
更改构造函数以接受字符串集合。
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在这里。
将构造函数中的参数重命名为
text
不同的名称(例如singletext
)并不理想,因为 Json.NET 将传递null
缺少的构造函数值,该值最初将被添加到Text
集合中,并将保留在那里,除非随后在反序列化期间替换集合。演示小提琴#4在这里。
相关阅读:
推荐阅读
- javascript - Uncaught (in promise) TypeError: .filter is not a function 。试图从 json 文件中获取数据
- pdf - 如何从表单提交的电子表格中收集数据并基于模板保存 PDF?
- python - 如何根据另一行合并python中的行?
- python - Protobuf 生成的 Python 包内部的隐式相对导入使得从外部导入是不可能的
- javascript - 在车把中,如何知道我是否在最后一次出现父数组
- react-native - 如何在expo react native中创建csv文件
- flutter - 如何使用 Flutter 防御性地从 Firestore 请求数据
- java - 工件的 Maven 依赖问题 - spring-boot-starter-test
- python - 如何使用 python 修复“selenium.common.exceptions.WebDriverException: Message: Failed to write request to stream”
- java - 如何在画布android中增加阴影的不透明度/强度?