fix JsonNode deserialising from null (#85463)
authoradj123 <adamjones123@hotmail.co.uk>
Wed, 10 May 2023 14:00:36 +0000 (15:00 +0100)
committerGitHub <noreply@github.com>
Wed, 10 May 2023 14:00:36 +0000 (15:00 +0100)
* fix JsonNode deserialising from null

* add further tests for more null-deserialising scenarios

---------

Co-authored-by: Adam Jones <ajones@drwuk.com>
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Node/JsonArrayConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Node/JsonNodeConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Node/JsonObjectConverter.cs
src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonNodeTests.cs

index 17b955c..bd44ed1 100644 (file)
@@ -20,6 +20,8 @@ namespace System.Text.Json.Serialization.Converters
             {
                 case JsonTokenType.StartArray:
                     return ReadList(ref reader, options.GetNodeOptions());
+                case JsonTokenType.Null:
+                    return null;
                 default:
                     Debug.Assert(false);
                     throw ThrowHelper.GetInvalidOperationException_ExpectedArray(reader.TokenType);
index 5dd032c..4076784 100644 (file)
@@ -61,6 +61,8 @@ namespace System.Text.Json.Serialization.Converters
                     return ObjectConverter.Read(ref reader, typeToConvert, options);
                 case JsonTokenType.StartArray:
                     return ArrayConverter.Read(ref reader, typeToConvert, options);
+                case JsonTokenType.Null:
+                    return null;
                 default:
                     Debug.Assert(false);
                     throw new JsonException();
index fa4dce9..860009c 100644 (file)
@@ -45,6 +45,8 @@ namespace System.Text.Json.Serialization.Converters
             {
                 case JsonTokenType.StartObject:
                     return ReadObject(ref reader, options.GetNodeOptions());
+                case JsonTokenType.Null:
+                    return null;
                 default:
                     Debug.Assert(false);
                     throw ThrowHelper.GetInvalidOperationException_ExpectedObject(reader.TokenType);
index cabcf40..a90d59a 100644 (file)
@@ -1,6 +1,8 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using System.Collections;
+using System.Collections.Generic;
 using Xunit;
 
 namespace System.Text.Json.Nodes.Tests
@@ -39,7 +41,20 @@ namespace System.Text.Json.Nodes.Tests
             Assert.IsAssignableFrom<JsonValue>(JsonNode.Parse("\"str\""));
             Assert.IsAssignableFrom<JsonValue>(JsonNode.Parse(ToUtf8("\"str\"")));
             Assert.IsType<JsonElement>(JsonSerializer.Deserialize<object>("\"str\""));
+
+            JsonType_Deserializes_Null<JsonNode>();
+            JsonType_Deserializes_Null<JsonArray>();
+            JsonType_Deserializes_Null<JsonObject>();
+        }
+
+        private static void JsonType_Deserializes_Null<TNode>() where TNode : JsonNode
+        {
+            Assert.Null(JsonSerializer.Deserialize<TNode>("null"));
+            Assert.Collection(JsonSerializer.Deserialize<TNode[]>("[null]"), Assert.Null);
+            Assert.Collection(JsonSerializer.Deserialize<IReadOnlyDictionary<string, TNode>>("{ \"Value\": null }"), kv => Assert.Null(kv.Value));
+            Assert.Null(JsonSerializer.Deserialize<ObjectWithNodeProperty<TNode>>("{ \"Value\": null }").Value);
         }
+        private record ObjectWithNodeProperty<TNode>(TNode Value) where TNode : JsonNode;
 
         [Fact]
         public static void AsMethods_Throws()