Skip to content

Commit 83b9266

Browse files
Use maximum available value for JSON serialization depth (#19001)
* Use maximum available value for JSON serialization depth. * Updated unittests with best practices --------- Co-authored-by: Migaroez <[email protected]>
1 parent 7fe6971 commit 83b9266

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

src/Umbraco.Cms.Api.Management/Serialization/ConfigureUmbracoBackofficeJsonOptions.cs

+2
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,7 @@ public void Configure(JsonOptions options)
3636
options.JsonSerializerOptions.Converters.Add(new JsonObjectConverter());
3737

3838
options.JsonSerializerOptions.TypeInfoResolver = _umbracoJsonTypeInfoResolver;
39+
40+
options.JsonSerializerOptions.MaxDepth = 64; // Ensures the maximum possible value is used, in particular to support handling as best we can levels of nested blocks.
3941
}
4042
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using System.Text.Json;
2+
using Microsoft.AspNetCore.Mvc;
3+
using NUnit.Framework;
4+
using Umbraco.Cms.Api.Common.Serialization;
5+
using Umbraco.Cms.Api.Management.Serialization;
6+
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
7+
8+
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Cms.Api.Management.Serialization;
9+
10+
[TestFixture]
11+
public class BackOfficeSerializationTests
12+
{
13+
private JsonOptions jsonOptions;
14+
15+
[SetUp]
16+
public void SetupOptions()
17+
{
18+
var typeInfoResolver = new UmbracoJsonTypeInfoResolver(TestHelper.GetTypeFinder());
19+
var configurationOptions = new ConfigureUmbracoBackofficeJsonOptions(typeInfoResolver);
20+
var options = new JsonOptions();
21+
configurationOptions.Configure(global::Umbraco.Cms.Core.Constants.JsonOptionsNames.BackOffice, options);
22+
jsonOptions = options;
23+
}
24+
25+
[Test]
26+
public void Will_Serialize_To_Camel_Case()
27+
{
28+
var objectToSerialize = new UnNestedJsonTestValue();
29+
30+
var json = JsonSerializer.Serialize(objectToSerialize, jsonOptions.JsonSerializerOptions);
31+
32+
Assert.AreEqual("{\"stringValue\":\"theValue\"}", json);
33+
}
34+
35+
// the limit is 64, but it seems like the functional limit is that minus 1
36+
[TestCase(1, true, TestName = "Can_Serialize_At_Min_Depth(1)")]
37+
[TestCase(48, true, TestName = "Can_Serialize_At_High_Depth(33)")]
38+
[TestCase(63, true, TestName = "Can_Serialize_To_Max_Depth(63)")]
39+
[TestCase(64, false, TestName = "Can_NOT_Serialize_Beyond_Max_Depth(64)")]
40+
public void Can_Serialize_To_Max_Depth(int depth, bool shouldPass)
41+
{
42+
var objectToSerialize = CreateNestedObject(depth);
43+
44+
if (shouldPass)
45+
{
46+
var json = JsonSerializer.Serialize(objectToSerialize, jsonOptions.JsonSerializerOptions);
47+
Assert.IsNotEmpty(json);
48+
}
49+
else
50+
{
51+
Assert.Throws<JsonException>(() => JsonSerializer.Serialize(objectToSerialize, jsonOptions.JsonSerializerOptions));
52+
}
53+
}
54+
55+
private static NestedJsonTestValue CreateNestedObject(int levels)
56+
{
57+
var root = new NestedJsonTestValue { Level = 1 };
58+
var outer = root;
59+
for (var i = 2; i <= levels; i++)
60+
{
61+
var inner = new NestedJsonTestValue { Level = i };
62+
outer.Inner = inner;
63+
outer = inner;
64+
}
65+
66+
return root;
67+
}
68+
69+
public class UnNestedJsonTestValue
70+
{
71+
public string StringValue { get; set; } = "theValue";
72+
}
73+
74+
public class NestedJsonTestValue
75+
{
76+
public int Level { get; set; }
77+
78+
public NestedJsonTestValue? Inner { get; set; }
79+
}
80+
}

0 commit comments

Comments
 (0)