Skip to content

Commit 9121b72

Browse files
authored
[Blazor] Ensure System.Text.Json RespectRequiredConstructorParametersDefault can be enabled (#62366)
* Enable `RespectRequiredConstructorParametersDefault` to ensure it can be set on user's apps. * Add a null parameter default value to the ResourceAsset constructor.
1 parent 2cbe5b1 commit 9121b72

File tree

5 files changed

+74
-2
lines changed

5 files changed

+74
-2
lines changed

src/Components/Components/src/PublicAPI.Shipped.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,6 @@ Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrameType.Region = 5 -> Mic
417417
Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrameType.Text = 2 -> Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrameType
418418
Microsoft.AspNetCore.Components.ResourceAsset
419419
Microsoft.AspNetCore.Components.ResourceAsset.Properties.get -> System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Components.ResourceAssetProperty!>?
420-
Microsoft.AspNetCore.Components.ResourceAsset.ResourceAsset(string! url, System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Components.ResourceAssetProperty!>? properties) -> void
421420
Microsoft.AspNetCore.Components.ResourceAsset.Url.get -> string!
422421
Microsoft.AspNetCore.Components.ResourceAssetCollection
423422
Microsoft.AspNetCore.Components.ResourceAssetCollection.IsContentSpecificUrl(string! path) -> bool

src/Components/Components/src/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#nullable enable
2+
Microsoft.AspNetCore.Components.ResourceAsset.ResourceAsset(string! url, System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Components.ResourceAssetProperty!>? properties = null) -> void
23
Microsoft.AspNetCore.Components.Routing.Router.NotFoundPage.get -> System.Type!
34
Microsoft.AspNetCore.Components.Routing.Router.NotFoundPage.set -> void
45
Microsoft.AspNetCore.Components.Infrastructure.ComponentsMetricsServiceCollectionExtensions

src/Components/Components/src/ResourceAsset.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Components;
1212
/// <param name="url">The URL of the resource.</param>
1313
/// <param name="properties">The properties associated to this resource.</param>
1414
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
15-
public sealed class ResourceAsset(string url, IReadOnlyList<ResourceAssetProperty>? properties)
15+
public sealed class ResourceAsset(string url, IReadOnlyList<ResourceAssetProperty>? properties = null)
1616
{
1717
/// <summary>
1818
/// Gets the URL that identifies this resource.

src/Components/Components/test/ResourceAssetCollectionTest.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Text.Json;
5+
using System.Text.Json.Serialization;
6+
47
namespace Microsoft.AspNetCore.Components;
58

69
public class ResourceAssetCollectionTest
@@ -85,4 +88,68 @@ [new ResourceAssetProperty("label", "image2.jpg")]),
8588
Assert.False(isContentSpecificUrl1);
8689
Assert.True(isContentSpecificUrl2);
8790
}
91+
92+
[Fact]
93+
public void ResourceAsset_CanSerializeAndDeserialize_WithoutRespectRequiredConstructorParameters()
94+
{
95+
// Arrange
96+
var originalAsset = new ResourceAsset("test-url", null);
97+
var options = new JsonSerializerOptions { WriteIndented = true };
98+
99+
// Act
100+
var json = JsonSerializer.Serialize(originalAsset, options);
101+
var deserializedAsset = JsonSerializer.Deserialize<ResourceAsset>(json, options);
102+
103+
// Assert
104+
Assert.NotNull(deserializedAsset);
105+
Assert.Equal("test-url", deserializedAsset.Url);
106+
Assert.Null(deserializedAsset.Properties);
107+
}
108+
109+
[Fact]
110+
public void ResourceAsset_CanSerializeAndDeserialize_WithRespectRequiredConstructorParameters()
111+
{
112+
// Arrange
113+
var originalAsset = new ResourceAsset("test-url", null);
114+
var options = new JsonSerializerOptions
115+
{
116+
WriteIndented = true,
117+
RespectRequiredConstructorParameters = true
118+
};
119+
120+
// Act
121+
var json = JsonSerializer.Serialize(originalAsset, options);
122+
var deserializedAsset = JsonSerializer.Deserialize<ResourceAsset>(json, options);
123+
124+
// Assert
125+
Assert.NotNull(deserializedAsset);
126+
Assert.Equal("test-url", deserializedAsset.Url);
127+
Assert.Null(deserializedAsset.Properties);
128+
}
129+
130+
[Fact]
131+
public void ResourceAsset_WithSourceGenerationContext_CanSerializeAndDeserializeWithRespectRequiredConstructorParameters()
132+
{
133+
// Arrange - this test simulates the context from ResourceCollectionUrlEndpoint
134+
var originalAsset = new ResourceAsset("test-url", null);
135+
var assets = new List<ResourceAsset> { originalAsset };
136+
137+
// Use a custom JsonSerializerOptions that mimics the source-generated context behavior
138+
var options = new JsonSerializerOptions
139+
{
140+
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
141+
WriteIndented = false,
142+
RespectRequiredConstructorParameters = true
143+
};
144+
145+
// Act
146+
var json = JsonSerializer.Serialize<IReadOnlyList<ResourceAsset>>(assets, options);
147+
var deserializedAssets = JsonSerializer.Deserialize<IReadOnlyList<ResourceAsset>>(json, options);
148+
149+
// Assert
150+
Assert.NotNull(deserializedAssets);
151+
Assert.Single(deserializedAssets);
152+
Assert.Equal("test-url", deserializedAssets[0].Url);
153+
Assert.Null(deserializedAssets[0].Properties);
154+
}
88155
}

src/Components/test/testassets/Directory.Build.props

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,9 @@
2525
<PropertyGroup>
2626
<BlazorCacheBootResources>false</BlazorCacheBootResources>
2727
</PropertyGroup>
28+
29+
<ItemGroup>
30+
<!-- Enable RespectRequiredConstructorParametersDefault to test compatibility -->
31+
<RuntimeHostConfigurationOption Include="System.Text.Json.Serialization.RespectRequiredConstructorParametersDefault" Value="true" />
32+
</ItemGroup>
2833
</Project>

0 commit comments

Comments
 (0)