diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets
index cb644757a2d95..348a71ba8da89 100644
--- a/src/libraries/Directory.Build.targets
+++ b/src/libraries/Directory.Build.targets
@@ -7,6 +7,18 @@
$(TestStrongNameKeyId)
+
+
+
+ true
+ true
+ true
+
+
@@ -47,14 +59,6 @@
-->
$(WarningsAsErrors.Replace('NU1605', ''))
-
- true
- true
- true
false
diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj
index 5765b6cdbee86..3e867457e45ba 100644
--- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj
+++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj
@@ -8,6 +8,8 @@
CS8969
true
true
+ true
+ 1
Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data.
The System.Text.Json library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks.
diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs
index 8dc0924ad36e6..32096972d6df7 100644
--- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs
+++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs
@@ -174,13 +174,7 @@ internal JsonArray(JsonElement element, JsonNodeOptions? options = null) : base(
[RequiresDynamicCode(JsonValue.CreateDynamicCodeMessage)]
public void Add(T? value)
{
- JsonNode? nodeToAdd = value switch
- {
- null => null,
- JsonNode node => node,
- _ => JsonValue.Create(value, Options)
- };
-
+ JsonNode? nodeToAdd = ConvertFromValue(value, Options);
Add(nodeToAdd);
}
diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs
index a06fc47cfc1c4..43b6048828a84 100644
--- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs
+++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs
@@ -3,6 +3,8 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+using System.Text.Json.Serialization.Converters;
+using System.Text.Json.Serialization.Metadata;
namespace System.Text.Json.Nodes
{
@@ -316,17 +318,16 @@ public static bool DeepEquals(JsonNode? node1, JsonNode? node2)
[RequiresDynamicCode(JsonValue.CreateDynamicCodeMessage)]
public void ReplaceWith(T value)
{
+ JsonNode? node;
switch (_parent)
{
- case null:
- return;
case JsonObject jsonObject:
- JsonValue? jsonValue = JsonValue.Create(value);
- jsonObject.SetItem(GetPropertyName(), jsonValue);
+ node = ConvertFromValue(value);
+ jsonObject.SetItem(GetPropertyName(), node);
return;
case JsonArray jsonArray:
- JsonValue? jValue = JsonValue.Create(value);
- jsonArray.SetItem(GetElementIndex(), jValue);
+ node = ConvertFromValue(value);
+ jsonArray.SetItem(GetElementIndex(), node);
return;
}
}
@@ -351,5 +352,33 @@ internal void AssignParent(JsonNode parent)
Parent = parent;
}
+
+ ///
+ /// Adaptation of the equivalent JsonValue.Create factory method extended
+ /// to support arbitrary and values.
+ /// TODO consider making public cf. https://github.com/dotnet/runtime/issues/70427
+ ///
+ [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)]
+ [RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)]
+ internal static JsonNode? ConvertFromValue(T? value, JsonNodeOptions? options = null)
+ {
+ if (value is null)
+ {
+ return null;
+ }
+
+ if (value is JsonNode node)
+ {
+ return node;
+ }
+
+ if (value is JsonElement element)
+ {
+ return JsonNodeConverter.Create(element, options);
+ }
+
+ var jsonTypeInfo = (JsonTypeInfo)JsonSerializerOptions.Default.GetTypeInfo(typeof(T));
+ return new JsonValueCustomized(value, jsonTypeInfo, options);
+ }
}
}
diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs
index 8f115d44b211f..ef51703958151 100644
--- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs
+++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs
@@ -680,5 +680,74 @@ public static void ReplaceWith()
Assert.Null(jValue.Parent);
Assert.Equal("[5]", jArray.ToJsonString());
}
+
+ [Theory]
+ [InlineData("null")]
+ [InlineData("1")]
+ [InlineData("false")]
+ [InlineData("\"str\"")]
+ [InlineData("""{"test":"hello world"}""")]
+ [InlineData("[1,2,3]")]
+ public static void AddJsonElement(string json)
+ {
+ // Regression test for https://github.com/dotnet/runtime/issues/94842
+ using var jdoc = JsonDocument.Parse(json);
+ var array = new JsonArray();
+
+ array.Add(jdoc.RootElement);
+
+ JsonNode arrayElement = Assert.Single(array);
+ switch (jdoc.RootElement.ValueKind)
+ {
+ case JsonValueKind.Object:
+ Assert.IsAssignableFrom(arrayElement);
+ break;
+ case JsonValueKind.Array:
+ Assert.IsAssignableFrom(arrayElement);
+ break;
+ case JsonValueKind.Null:
+ Assert.Null(arrayElement);
+ break;
+ default:
+ Assert.IsAssignableFrom(arrayElement);
+ break;
+ }
+ Assert.Equal($"[{json}]", array.ToJsonString());
+ }
+
+ [Theory]
+ [InlineData("null")]
+ [InlineData("1")]
+ [InlineData("false")]
+ [InlineData("\"str\"")]
+ [InlineData("""{"test":"hello world"}""")]
+ [InlineData("[1,2,3]")]
+ public static void ReplaceWithJsonElement(string json)
+ {
+ // Regression test for https://github.com/dotnet/runtime/issues/94842
+ using var jdoc = JsonDocument.Parse(json);
+ var array = new JsonArray { 1 };
+
+ array[0].ReplaceWith(jdoc.RootElement);
+
+ JsonNode arrayElement = Assert.Single(array);
+ switch (jdoc.RootElement.ValueKind)
+ {
+ case JsonValueKind.Object:
+ Assert.IsAssignableFrom(arrayElement);
+ break;
+ case JsonValueKind.Array:
+ Assert.IsAssignableFrom(arrayElement);
+ break;
+ case JsonValueKind.Null:
+ Assert.Null(arrayElement);
+ break;
+ default:
+ Assert.IsAssignableFrom(arrayElement);
+ break;
+ }
+
+ Assert.Equal($"[{json}]", array.ToJsonString());
+ }
}
}