Generated JSON deserializer fails at runtime when schema enum contains duplicate keys
#800 opened on Oct 28, 2018
Repository metrics
- Stars
- (1,578 stars)
- PR merge metrics
- (No merged PRs in 30d)
Description
The following is the definition of the System.Net.HttpStatusCode type (shortened) from .nuget\packages\netstandard.library\2.0.3\build\netstandard2.0\ref\netstandard.dll:
namespace System.Net
{
//
// Summary:
// Contains the values of status codes defined for HTTP.
public enum HttpStatusCode
{
//
// Summary:
// Equivalent to HTTP status 300. System.Net.HttpStatusCode.Ambiguous indicates
// that the requested information has multiple representations. The default action
// is to treat this status as a redirect and follow the contents of the Location
// header associated with this response.
Ambiguous = 300,
//
// Summary:
// Equivalent to HTTP status 300. System.Net.HttpStatusCode.MultipleChoices indicates
// that the requested information has multiple representations. The default action
// is to treat this status as a redirect and follow the contents of the Location
// header associated with this response.
MultipleChoices = 300,
}
}
Per this StackOverflow question (which references the C# spec), this is allowed and correct syntax.
Generating the schema
var jsonSchema = (await NJsonSchema.JsonSchema4.FromTypeAsync(typeof(System.Net.HttpStatusCode))).ToJson();
Produces this (shortened) JSON schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "HttpStatusCode",
"type": "integer",
"description": "",
"x-enumNames": [
"MultipleChoices",
"Ambiguous"
],
"enum": [
300,
300
]
}
After a bit more processing (I'm using a model containing a HttpStatusCode property in a Web API, which gets then converted via NSwag to a Swagger definition, which then again is used to create a C# client) this is the generated C# client code (shortened):
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.11.0.0 (Newtonsoft.Json v9.0.0.0)")]
public enum HttpStatusCode
{
[System.Runtime.Serialization.EnumMember(Value = "Ambiguous")]
MultipleChoices = 14,
[System.Runtime.Serialization.EnumMember(Value = "Ambiguous")]
Ambiguous = 15
}
This just fails at runtime when deserializing with Newtonsoft.Json:
System.InvalidOperationException : Enum name 'Ambiguous' already exists on enum 'HttpStatusCode'.
The workaround for me is to simply use the System.Net.HttpStatusCode enum in my generated client instead of the generated one.