我正在使用。net 5.0中的一个POCO类,我需要在浏览器之间进行序列化和反序列化,而这是在一个库中,我不想告诉用户他们必须使用哪个序列化器。
所以我试着让它和Newtonsoft一起工作。Json和System.Text.Json.
我的问题是,在System.Text.Json中,存储在类型为object的字段中的值没有被反序列化成它们的原始类型。
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。字符串,但是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反序列化这个类型?
Dennis指向https://github.com/dotnet/runtime/issues/31408它被关闭为https://github.com/dotnet/runtime/issues/29960的副本。
所以答案是,你没有。
来自GitHub上的讨论:
这是设计的(不太可能改变)。由于对象类型可以将JSON有效负载映射到任何。net类型,因此在反序列化时,JsonSerializer返回一个盒装的JsonElement,而不是指向JSON令牌本身。在反序列化期间,我们不会试图从JSON有效负载推断或猜测。net类型,因此,调用者(有足够的上下文)需要将返回的JsonElement转换为预期的。net类型。
如果你正在尝试做我正在尝试做的事情,在一个实用程序库中创建一个POCO类,该类可以由库的客户端序列化和反序列化,而不需要库的用户做任何特别的努力,不要使用object。
在我的例子中,我有一个可能包含字符串、int、double、decimal或datetime的字段。我将不得不将其替换为每个单独的可空字段。