Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enumeration values don't respect original letter casing in generated C# clients when used in URL query #1052

Closed
vojtechvit opened this issue Nov 8, 2017 · 6 comments

Comments

@vojtechvit
Copy link

Enumeration values don't respect original letter casing in generated C# clients when used in URL query

Sample Swagger:

{
  "swagger": "2.0",
  "paths": {
    "/config": {
      
      "get": {
        "operationId": "getAppConfig",
        "parameters": [
          {
            "name": "include",
            "description": "A comma delimited list of config objects to return.\nIf none specified then all configuration is returned.\n",
            "in": "query",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "sitemap",
                "navigation",
                "general",
                "i18n"
              ]
            },
            "collectionFormat": "csv"
          }
        ],
        "responses": {
          "204": {
            "description": "The list of available pages"
          }
        }
      }
    }
  }
}

The generated enumeration POCO (NSwagStudio v11.12.5.0):

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.10.5.0 (Newtonsoft.Json v9.0.0.0)")]
public enum Anonymous
{
	[System.Runtime.Serialization.EnumMember(Value = "sitemap")]
	Sitemap = 0,

	[System.Runtime.Serialization.EnumMember(Value = "navigation")]
	Navigation = 1,

	[System.Runtime.Serialization.EnumMember(Value = "general")]
	General = 2,

	[System.Runtime.Serialization.EnumMember(Value = "i18n")]
	I18n = 3,
}

The generated C# client method (NSwagStudio v11.12.5.0):

public async System.Threading.Tasks.Task GetAppConfigAsync(System.Collections.Generic.IEnumerable<Anonymous> include, System.Threading.CancellationToken cancellationToken)
{
	var urlBuilder_ = new System.Text.StringBuilder();
	urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/config?");
	if (include != null) foreach (var item_ in include) { urlBuilder_.Append("include=").Append(System.Uri.EscapeDataString(System.Convert.ToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append("&"); }
	urlBuilder_.Length--;

	var client_ = new System.Net.Http.HttpClient();

The requests sent by this method will use property names instead of EnumMember values.

I expect that the same issue may happen in URL paths.

@vojtechvit
Copy link
Author

This causes my proxy to fail because the 3rd party API is case-sensitive :-/

@RicoSuter
Copy link
Owner

RicoSuter commented Nov 10, 2017

The problem here is that System.Convert.ToString(enum) uses the enum name instead of the EnumMemberAttribute.Value... How could we fix that in the simplest way?

@vojtechvit
Copy link
Author

looks like there is no specific reusable function to do that in the BCL. All resources I found suggested to use reflection directly, e.g. https://forums.asp.net/t/2050963.aspx?How+to+get+EnumMember+value+

@vojtechvit
Copy link
Author

Alternatively we could use some NuGet library to support it, but that would require introducing a 3rd party dependency... https://www.nuget.org/packages?q=string+enum

@RicoSuter
Copy link
Owner

It’s important that the generated code does not depend on 3rd party libraries except the BCL and Newtonsoft.Json (which cant be avoided). The biggest problem is, that we may need conditional logic for enums which make the templates even more complicated. We could however use:

JsonConvert.SerializeObject(param).Trim(‘“‘)

@tiagopsantos
Copy link

This is issue still occurs - 14.1.0.0 , when creating C# Client

  "someEnum": {
    "type": "object",
    "properties": {
      "someEnumProperty": {
        "description": "",
        "enum": [
          "M",
          "S",
          "R",
          "L",
          "T",
          "m",
          "Y",
          "C",
          "N",
          "W",
          "w"
        ],
        "example": "R",
        "type": "string",
        "maxLength": 1
      }
    }
  }

When generating the C# Client:
`

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")]
public enum SomeEnumProperty
{
    [System.Runtime.Serialization.EnumMember(Value = @"M")]
    M = 0,
    [System.Runtime.Serialization.EnumMember(Value = @"S")]
    S = 1,
    [System.Runtime.Serialization.EnumMember(Value = @"R")]
    R = 2,
    [System.Runtime.Serialization.EnumMember(Value = @"L")]
    L = 3,
    [System.Runtime.Serialization.EnumMember(Value = @"T")]
    T = 4,
    [System.Runtime.Serialization.EnumMember(Value = @"m")]
    M = 5,
    [System.Runtime.Serialization.EnumMember(Value = @"Y")]
    Y = 6,
    [System.Runtime.Serialization.EnumMember(Value = @"C")]
    C = 7,
    [System.Runtime.Serialization.EnumMember(Value = @"N")]
    N = 8,
    [System.Runtime.Serialization.EnumMember(Value = @"W")]
    W = 9,
    [System.Runtime.Serialization.EnumMember(Value = @"w")]
    W = 10,
}`

The first Case is in Upper, so it generates two W enum item

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants