RicoSuter/NJsonSchema

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

Open

#800 aberto em 28 de out. de 2018

Ver no GitHub
 (2 comments) (0 reactions) (0 assignees)C# (550 forks)github user discovery
help wantedtype: bug

Métricas do repositório

Stars
 (1.578 stars)
Métricas de merge de PR
 (Nenhuma PRs mesclada em 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.

Guia do colaborador