gpt4 book ai didi

How to deserialize array with null values?(如何反序列化具有空值的数组?)

翻译 作者:bug小助手 更新时间:2023-10-26 22:29:14 26 4
gpt4 key购买 nike



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]”);应该是可行的。

Looks like this was fixed in .NET 8 preview 5, see github.com/dotnet/runtime/pull/85463.

看起来这个问题已经在.NET8预览版5中修复了,请访问githorb.com/dotnet/untime/ull/85463。

优秀答案推荐

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

JsonNode是一个抽象类,也是JsonObject和JsonArray的基类。但是JsonArray和JsonObject[]是完全不同的。我不知道你为什么需要它,但你不能直接将JSON字符串格式化。但是有一个技巧,你可以使用LINQ Select和ToList


string toJson = JsonSerializer.Serialize(new List<JsonNode>{ null });

List<JsonNode> fromJson = JsonArray.Parse(toJson)
.AsArray()
.Select(v => v.Deserialize<JsonNode>())
.ToList();
//or

List<JsonNode> fromJson = JsonSerializer.Deserialize<List<JsonElement>>(toJson)
.Select(v => v.Deserialize<JsonNode>() )
.ToList();




Update this is a bug in System.Text.Json which has been fixed in .NET 8 as of Preview 5. See:

更新这是System.Text.Json中的错误,该错误已在.NET 8预览版5中修复。请参阅:



A failing .NET 7 demo fiddle was created here.

这里创建了一个失败的.NET7演示小提琴。


As a workaround in earlier versions, you could create a custom converter for List<JsonNode> like the following:

作为早期版本中的一种解决办法,您可以为List 创建一个自定义转换器,如下所示:


public class JsonNodeListConverter : JsonConverter<IEnumerable<JsonNode?>>
{
public override bool CanConvert(Type objectType) =>
objectType == typeof(List<JsonNode>) || objectType == typeof(IReadOnlyList<JsonNode>) || objectType == typeof(IReadOnlyCollection<JsonNode>) || objectType == typeof(JsonNode []) || objectType == typeof(IEnumerable<JsonNode>);
public override void Write(Utf8JsonWriter writer, IEnumerable<JsonNode?> value, JsonSerializerOptions options)
{
writer.WriteStartArray();
foreach (var node in value)
JsonSerializer.Serialize(writer, node, options);
writer.WriteEndArray();
}

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.

并且您将能够反序列化包含空值的JsonNode的列表和数组。


Demo fiddle #2 here.

演示小提琴2号在这里。


Alternatively, you could deserialize to an intermediate IEnumerable<object> with the option JsonSerializerOptions.UnknownTypeHandling = JsonUnknownTypeHandling.JsonNode and your non-null JSON array values will be deserialized as JsonNode subtypes:

或者,您可以使用选项JsonSerializerOptions.UnnownTypeHandling=JsonUnnownTypeHandling.JsonNode将非空的JSON数组值反序列化为JsonNode子类型,并将其反序列化为中间IEumable


var options = new JsonSerializerOptions
{
UnknownTypeHandling = JsonUnknownTypeHandling.JsonNode,
};
var list = JsonSerializer.Deserialize<IEnumerable<object>>("""[null, [null], 1, {}, "a"]""",
options)
?.Cast<JsonNode?>().ToList();

Demo fiddle #3 here.

演示小提琴#3在这里。


更多回答

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.)

JsonNode是一个抽象类,因此不能直接反序列化json字符串。--实际上你可以,例如,JsonSerializer.Deserialize(“[null]”)运行得很好,请参见dotnetfiddle.net/mzUyKm。虽然JsonNode是抽象的,但它是内置类型,因此System.Text.Json知道(在OP的情况下除外)根据实际的JSON使用正确的具体类型。(Json.NET的功能类似,因为您可以反序列化为JToken,然后将创建正确的具体子类。)

@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>

@DBC你读了问题了吗?这就是列出node=System.Text.Json的问题。JsonSerializer.Deserialize(toJson)“[null]”)抛出该异常。OP需要一个列表,而不仅仅是一个JsonNode。JsonArray和List有很大的不同。List可以等于List或List

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.

我确实读过这条问题。并且您的两个代码样例都运行良好,并将“[NULL]”反序列化为一个列表。但是您的解释是,JsonNode是一个抽象类,因此您不能直接反序列化JSON字符串。并不完全正确。您可以在许多情况下反序列化为JsonNode(或List),尽管它是抽象的。例如,JsonSerializer.Deserialize>(“”“[1,”a“]”);运行良好。“[NULL]”失败并不是因为JsonNode是抽象的,而是因为在集合内将NULL反序列化为JsonNode的System.Text.Json中存在错误。

@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.

@DBC我很抱歉,但我讨厌冗长的解释,我从来不读对答案的任何解释,只读代码。我认为一个真正的程序员不需要任何代码解释。如果一个人需要解释,他应该选择另一个职业。但仅仅是因为我对你的尊重,我更新了我的答案。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com