Minimal API: JsonStringEnumMemberName doesn't work while deserializing query params & headers
Is there an existing issue for this?
- [x] I have searched the existing issues
Describe the bug
I used this new .NET 9 attribute to customize enum names and it errors out during request parsing/deserialization: http://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/customize-properties#custom-enum-member-names
Expected Behavior
I set up my enum like this:
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum TestEnum
{
[JsonStringEnumMemberName("one")]
A1,
[JsonStringEnumMemberName("two")]
A2,
}
I expected this call to not error out http://localhost:5274/?testEnum=one
All of these work:
http://localhost:5274/?testEnum=A1
http://localhost:5274/?testEnum=0
This also works:
Console.WriteLine(JsonSerializer.Deserialize<TestEnum>("\"one\"")); // A1
Steps To Reproduce
Program.cs:
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
var app = builder.Build();
app.MapGet("/", ([FromQuery] TestEnum? testEnum = null) =>
{
Console.WriteLine(testEnum);
Console.WriteLine(JsonSerializer.Deserialize<TestEnum>("\"one\""));
return testEnum;
});
app.Run();
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum TestEnum
{
[JsonStringEnumMemberName("one")]
A1,
[JsonStringEnumMemberName("two")]
A2,
}
csproj:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
Exceptions (if any)
400
.NET Version
9.0.300
Anything else?
No response
Update:
Parsing from body works fine.
app.MapPost("/", ([FromBody] TestEnum? testEnum = null) =>
{
Console.WriteLine(testEnum);
Console.WriteLine(JsonSerializer.Deserialize<TestEnum>("\"one\""));
return testEnum;
});
However, header doesn't.
app.MapPost("/", ([FromHeader(Name = "test-enum")] TestEnum? testEnum = null) =>
{
Console.WriteLine(testEnum);
Console.WriteLine(JsonSerializer.Deserialize<TestEnum>("\"one\""));
return testEnum;
});
Issue confirmed with .NET 9.0.6.
The only workaround found is to use a specific IModelBinder and do the manual conversion there from bindingContext.HttpContext.Request.Query; a bit ugly.
This is expected behavior. The attributes are specific to System.Text.JSON's serializer and only apply when when deserialize the body as JSON.
Resolving from the query or route uses simple 'TryParse' binding to bind the enum so the rules don't apply.
To customize behavior for binding from the route, you'll want to take advantage of BindAsync for custom binding.