-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
As the title suggests, JsonSourceGenerationOptionsAttribute(JsonSerializerDefaults defaults) is out of sync with JsonSerializerOptions(JsonSerializerDefaults defaults), despite the comment suggesting otherwise.
This leads to an ArgumentOutOfRangeException when the type is annotated with [JsonSourceGenerationOptionsAttribute(JsonSerializerDefaults.Strict)].
Reproduction Steps
using System.Text.Json;
using System.Text.Json.Serialization;
internal static class Reproduction
{
public static void Main()
{
// Crash at runtime
_ = typeof(SourceGenerationContext).GetCustomAttributes(true);
}
}
[JsonSourceGenerationOptions(JsonSerializerDefaults.Strict)]
[JsonSerializable(typeof(Example))]
internal partial class SourceGenerationContext : JsonSerializerContext;
internal class Example;Expected behavior
The returned array contains the JsonSourceGenerationOptions attribute with its properties configured analogously to a new JsonSerializerOptions(JsonSerializerDefaults.Strict).
Actual behavior
The program crashes with the following message, despite the enum value being valid:
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter 'defaults')
Regression?
No
Known Workarounds
Assign the attribute properties manually, referencing the JsonSerializerOptions(JsonSerializerDefaults defaults) constructor.
Configuration
- .NET 10.0.101
- Windows 11 24H2 (build 26100.7462)
- x64 architecture
The issue is specific to versions of .NET 10 past and including .NET 10 Preview 6.
Other information
The JsonSerializerDefaults.Strict enum value was implemented by #116271. The lack of support in the JsonSourceGenerationOptionsAttribute is likely an oversight.
Relevant code
runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs
Lines 170 to 191 in 2c8bf45
| public JsonSerializerOptions(JsonSerializerDefaults defaults) : this() | |
| { | |
| // Should be kept in sync with equivalent overload in JsonSourceGenerationOptionsAttribute | |
| if (defaults == JsonSerializerDefaults.Web) | |
| { | |
| _propertyNameCaseInsensitive = true; | |
| _jsonPropertyNamingPolicy = JsonNamingPolicy.CamelCase; | |
| _numberHandling = JsonNumberHandling.AllowReadingFromString; | |
| } | |
| else if (defaults == JsonSerializerDefaults.Strict) | |
| { | |
| _unmappedMemberHandling = JsonUnmappedMemberHandling.Disallow; | |
| _allowDuplicateProperties = false; | |
| _respectNullableAnnotations = true; | |
| _respectRequiredConstructorParameters = true; | |
| } | |
| else if (defaults != JsonSerializerDefaults.General) | |
| { | |
| throw new ArgumentOutOfRangeException(nameof(defaults)); | |
| } | |
| } |
runtime/src/libraries/System.Text.Json/Common/JsonSourceGenerationOptionsAttribute.cs
Lines 27 to 41 in 84d9854
| public JsonSourceGenerationOptionsAttribute(JsonSerializerDefaults defaults) | |
| { | |
| // Constructor kept in sync with equivalent overload in JsonSerializerOptions | |
| if (defaults is JsonSerializerDefaults.Web) | |
| { | |
| PropertyNameCaseInsensitive = true; | |
| PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase; | |
| NumberHandling = JsonNumberHandling.AllowReadingFromString; | |
| } | |
| else if (defaults is not JsonSerializerDefaults.General) | |
| { | |
| throw new ArgumentOutOfRangeException(nameof(defaults)); | |
| } | |
| } |