【发布时间】:2021-10-01 19:25:31
【问题描述】:
我正在使用 .NET 5.0 中的 POCO 类,我需要对浏览器进行序列化和反序列化,这是在一个库中,我不想告诉用户他们必须使用哪些序列化程序使用。
所以我试图让它与 Newtonsoft.Json 和 System.Text.Json 一起工作。
我的问题是存储在类型为 object 的字段中的值没有被反序列化为其原始类型,在 System.Text.Json 中。
using Shouldly;
using Xunit;
using SJ = System.Text.Json;
using NJ = Newtonsoft.Json;
public class SerializationTests
{
[Fact]
public void TestNJ()
{
var nvp = new NVP { Name = "a name", Value = "a value" };
var s = NJ.JsonConvert.SerializeObject(nvp);
var d = NJ.JsonConvert.DeserializeObject<NVP>(s);
d.ShouldBeEquivalentTo(nvp);
}
[Fact]
public void TestSJ()
{
var nvp = new NVP { Name = "a name", Value = "a value" };
var s = SJ.JsonSerializer.Serialize(nvp);
var d = SJ.JsonSerializer.Deserialize<NVP>(s);
d.ShouldBeEquivalentTo(nvp);
}
}
TestNJ 通过。
TestSJ 抛出异常:
预期值为 System.String,但为 System.Text.Json.JsonElement'
在调试器中很清楚发生了什么。
在 TestNJ() 和 TestSJ() 的开头,nvp 的值是:
nvp: {NVP}
Name [string]: "a name"
Value [object]: " a value"
在序列化之后,s 具有我期望的值:
"{\"Name\":\"a name\",\"Value\":\"a value\"}"
但是在TestNJ()中,反序列化后d的值是:
d: {NVP}
Name [string]: "a name"
Value [object]: " a value"
在 TestSJ() 中,d 的值为:
d: {NVP}
Name [string]: "a name"
Value [object]: ValueKind = String: "a value"
这里发生了什么?如何让 System.Text.Json 真正反序列化这种类型?
【问题讨论】:
-
在我看来这个 Github 问题是一样的。 deserialize object prop adds Valuekind to value #31408
-
您可以将
[JsonConverter(typeof(ObjectAsPrimitiveConverter))]应用到Value,其中ObjectAsPrimitiveConverter来自this answer 到C# - Deserializing nested json to nested Dictionary<string, object>。 -
虽然
DateTime对你没有帮助。 JSON 没有日期和时间的原始类型,因此它们只是被序列化为字符串。 Json.NET 和DataContractSerializer具有尝试推断字符串是否为日期的逻辑——但最好不要依赖这种逻辑,因为用户输入的字符串可能看起来像DateTime字符串。所以你的 DTO 解决方案看起来更好。
标签: c# json asp.net-core .net-core system.text.json