gRPC Transcoding: Invalid value for enum error when string enums enabled, integer values in swagger when string enums disabled
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 276
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
I'm attempting to use both GRPC json transcoding and the swagger interface. This application will have both grpc services and traditional web services. I want to use string json values for enums, so I configure json like so:
```CSharp
builder.Services
.AddControllers()
.AddJsonOptions(j =>
{
j.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
```
I also add grpc to the swagger gen:
```CSharp
builder.Services.AddGrpcSwagger();
```
When configuring json transcoding, I use the default `WriteEnumsAsIntegers` set to `false`, but even explicitly setting it the result is the same:
```CSharp
builder.Services
.AddGrpc()
.AddJsonTranscoding(opts =>
{
opts.JsonSettings.WriteEnumsAsIntegers = false;
});
```
Here I'm defining an enum in the proto file:
```
enum EnumParam {
ENUM_PARAM_UNSPECIFIED = 0;
ENUM_PARAM_VALUE1 = 1;
ENUM_PARAM_VALUE2 = 2;
}
```
And here I'm defining an rpc method (the `Request` message is not shown, but has a `param` field of type `EnumParam`):
```
rpc GetMethod(Request) returns (Reply) {
option (google.api.http) = {
get: "/v1/{param}"
};
}
```
When I open up the swagger UI for the API, the UI correctly lists `Value1` and `Value2` as valid values for the `param` argument of the `GetMethod`. However, when making the request through the UI, the following error is given:
```
Invalid value 'Value1' for enum type EnumParam.
```
Now, when I remove the `JsonStringEnumConverter` in the json settings, and go to the swagger page, the dropdown for the enum parameter no longer lists strings values, but rather integer values (in this case 1 and 2 for `Value1` and `Value2`, however the requests parse the enums properly.
### Expected Behavior
When using `JsonStringEnumConverter`, I would expect the values to be parsed correctly when selected in the swagger UI. Further, given that GRPC enums are serialized as strings by default, I think the default behavior, at least when `WriteEnumsAsIntegers` is set to `false`, is to still serialize gRPC json-transcoded endpoints as string values, even without a `JsonStringEnumConverter` specified for Asp.net controllers.
### Steps To Reproduce
Sorry I don't have a repro repo and the original source is under NDA. If you create a basic gRPC service from the template with the above additions/changes described above, you should be able to reproduce this issue, but let me know and I can work on a small repro repo - it will take some time.
### Exceptions (if any)
```
2025-03-12T14:05:49 info: Grpc.AspNetCore.Grpc.JsonTranscoding.ServerCallHandler[7]
2025-03-12T14:05:49 Error reading message.
2025-03-12T14:05:49 System.InvalidOperationException: Invalid value 'Value1' for enum type EnumParam.
2025-03-12T14:05:49 at Grpc.Shared.ServiceDescriptorHelpers.ConvertValue(Object value, FieldDescriptor descriptor)
2025-03-12T14:05:49 at Grpc.Shared.ServiceDescriptorHelpers.SetValue(IMessage message, FieldDescriptor field, Object values)
2025-03-12T14:05:49 at Grpc.Shared.ServiceDescriptorHelpers.RecursiveSetValue(IMessage currentValue, List`1 pathDescriptors, Object values)
2025-03-12T14:05:49 at Microsoft.AspNetCore.Grpc.JsonTranscoding.Internal.JsonRequestHelpers.ReadMessage[TRequest](JsonTranscodingServerCallContext serverCallContext, JsonSerializerOptions serializerOptions)
```
### .NET Version
9.0.200
### Anything else?
```
.NET SDK:
Version: 9.0.200
Commit: 90e8b202f2
Workload version: 9.0.200-manifests.69179adf
MSBuild version: 17.13.8+cbc39bea8
Runtime Environment:
OS Name: Windows
OS Version: 10.0.26100
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\9.0.200\
.NET workloads installed:
[wasm-tools-net6]
Installation Source: VS 17.13.35825.156
Manifest Version: 9.0.2/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.workload.mono.toolchain.net6\9.0.2\WorkloadManifest.json
Install Type: Msi
[wasm-tools-net8]
Installation Source: VS 17.13.35825.156
Manifest Version: 9.0.2/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.workload.mono.toolchain.net8\9.0.2\WorkloadManifest.json
Install Type: Msi
[wasm-tools]
Installation Source: VS 17.13.35825.156
Manifest Version: 9.0.2/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.workload.mono.toolchain.current\9.0.2\WorkloadManifest.json
Install Type: Msi
[aspire]
Installation Source: VS 17.13.35825.156
Manifest Version: 8.2.2/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.2.2\WorkloadManifest.json
Install Type: Msi
Configured to use loose manifests when installing new manifests.
Host:
Version: 9.0.2
Architecture: x64
Commit: 80aa709f5d
.NET SDKs installed:
9.0.200 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]
Environment variables:
Not set
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
```
Contributor guide
Assessment
This issue has not been assessed yet.