RicoSuter/NJsonSchema

Generated JSON deserializer fails at runtime when schema enum contains duplicate keys

Open

#800 aperta il 28 ott 2018

Vedi su GitHub
 (2 commenti) (0 reazioni) (0 assegnatari)C# (550 fork)github user discovery
help wantedtype: bug

Metriche repository

Star
 (1578 star)
Metriche merge PR
 (Nessuna PR mergiata in 30 g)

Descrizione

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.

Guida contributor