How to deserialize array with null values?(如何反序列化具有空值的数组?)
转载作者:bug小助手更新时间:2023-10-28 21:48:49284
I need to deserialize this json:
我需要反序列化这个json:
[null]
[空]
to a List<JsonNode>
添加到列表
unfortunately instead, I get this exception:
不幸的是,我得到了这样的例外:
System.Text.Json.JsonException: 'The JSON value could not be converted to System.Text.Json.Nodes.JsonNode. Path: $[0] | LineNumber: 0 | BytePositionInLine: 5.'
How to deserialize to a list with a single null value in it?
如何反序列化到一个只有一个空值的列表?
This code
此代码
var toJson = JsonSerializer.Serialize<List<JsonNode>>(new List<JsonNode>{ null });
Gives this json:
给出了这个json:
[null]
[空]
But this code
但是这个代码
var fromJson = JsonSerializer.Deserialize<List<JsonNode>>("[null]");
Throws above
在上方抛出
更多回答
JsonNode is abstract.
JsonNode是抽象的。
Tye to deserialize into var fromJson = JsonSerializer.Deserialize<List<JsonElement>>("[null]"); it should work.
将其反序列化为var from Json=JsonSerializer.Deserialize>(“[null]”);应该是可行的。
JsonNode is an abstract class and a base class for JsonObject and for a JsonArray. But JsonArray and JsonObject[] are completely different. I don't know why do you need it but you can not deserialize a json string directly. But there is a trick, you can use LINQ Select and ToList
public override IEnumerable<JsonNode?> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException(); var list = new List<JsonNode?>(); while (reader.ReadAndAssert().TokenType != JsonTokenType.EndArray) { list.Add(JsonSerializer.Deserialize<JsonNode>(ref reader, options)); } return typeToConvert.IsArray ? list.ToArray() : list; } }
public static class JsonExtensions { public static ref Utf8JsonReader ReadAndAssert(ref this Utf8JsonReader reader) { if (!reader.Read()) { throw new JsonException(); } return ref reader; } }
Then use as follows:
然后按如下方式使用:
var options = new JsonSerializerOptions { Converters = { new JsonNodeListConverter() }, }; JsonSerializer.Deserialize<List<JsonNode>>("""[null]""", options)
And you will be able to deserialize lists and arrays of JsonNode that include null values.
var options = new JsonSerializerOptions { UnknownTypeHandling = JsonUnknownTypeHandling.JsonNode, }; var list = JsonSerializer.Deserialize<IEnumerable<object>>("""[null, [null], 1, {}, "a"]""", options) ?.Cast<JsonNode?>().ToList();
JsonNode is an abstract class, so you can not deserialize a json string directly. -- actually you can, for instance JsonSerializer.Deserialize<JsonNode>("[null]") works just fine, see dotnetfiddle.net/mzUyKm. While abstract, JsonNode is a built-in type so System.Text.Json knows (except in OP's case) to use the correct concrete type depending on the actual JSON. (Json.NET functions similarly in that you can deserialize to a JToken and the correct concrete subclass will get created.)
@dbc Did you read the question? That is the problem that List<JsonNode> node = System.Text.Json. JsonSerializer.Deserialize<JsonNode>(toJson)"[null]") throws the exception. OP needs a LIST not just a JsonNode. There is a big difference between JsonArray and List<JsonObject>. List<JsonNode> maybe equal List<JsonArray> or List<JsonObject>
I did indeed read the question. And both your code samples works fine and deserialize "[null]" to a List<JsonNode>. But your explanation that JsonNode is an abstract class, so you can not deserialize a json string directly. is not quite right. You can deserialize to JsonNode (or List<JsonNode>) in many cases despite the fact that it is abstract. For instance JsonSerializer.Deserialize<List<JsonNode>>("""[1,"a"]"""); works fine. "[null]" fails not because JsonNode is abstract, but because there is a bug in System.Text.Json deserializing null to JsonNode inside collections.
@dbc I am sorry but I hate long explanations and never read any explanations to the answers, only the code. I think a real programmer doesn't need any code explanations. If a person needs explanations he should select another profession. But just because of my respect to you, I updated my answer.
我是一名优秀的程序员,十分优秀!