CSharp client generation does not generate valid c# for enums with int values. eg
enum Sex {
None=0,
Male=1,
Female=2
}
After running generate command with the below config
{ "packageName":"{ProjectName}"}
The resultant code:
[JsonConverter(typeof(StringEnumConverter))]
public enum Sex
{
/// <summary>
/// Enum NUMBER_0 for 0
/// </summary>
[EnumMember(Value = 0)]
NUMBER_0,
/// <summary>
/// Enum NUMBER_1 for 1
/// </summary>
[EnumMember(Value = 1)]
NUMBER_1,
/// <summary>
/// Enum NUMBER_2 for 2
/// </summary>
[EnumMember(Value = 2)]
NUMBER_2,
/// <summary>
/// Enum NUMBER_3 for 3
/// </summary>
[EnumMember(Value = 3)]
NUMBER_3
}
2.2.3
java -jar swagger-codegen-cli.jar generate -i %JSON_CONFIG% -l csharp -c "%APP_FOLDER%code-gen-config.json" -o "%APP_FOLDER%API"
@chidionuekwusi thanks for reporting the issue. What's the "correct" code look like?
I could find a test case here to cover integer enum in C#: https://github.com/swagger-api/swagger-codegen/blob/master/samples/client/petstore/csharp/SwaggerClient/src/IO.Swagger.Test/Model/EnumClassTests.cs#L66
@wing328 It looks to me like the issue is more about how swagger definitions define enums.
For example, defining a gender enum like this in definition:
gender:
type: string
enum:
- none
- male
- female
Results in this enum:
/// <summary>
/// Gets or Sets Gender
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum GenderEnum
{
/// <summary>
/// Enum None for "none"
/// </summary>
[EnumMember(Value = "none")]
None,
/// <summary>
/// Enum Male for "male"
/// </summary>
[EnumMember(Value = "male")]
Male,
/// <summary>
/// Enum Female for "female"
/// </summary>
[EnumMember(Value = "female")]
Female
}
Technically, this is correct and is the only way I know of to provide semantics to the enum's numbers. However, the enum is annotated with StringEnumConverter which means it is presented as none, male, or female to the api. This is correct, unfortunately.
If you define the enum as numbers with data type string:
gender:
type: string
enum:
- 0
- 1
- 2
You get the following enum (on master):
/// <summary>
/// Gets or Sets Gender
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum GenderEnum
{
/// <summary>
/// Enum _0 for "0"
/// </summary>
[EnumMember(Value = "0")]
_0,
/// <summary>
/// Enum _1 for "1"
/// </summary>
[EnumMember(Value = "1")]
_1,
/// <summary>
/// Enum _2 for "2"
/// </summary>
[EnumMember(Value = "2")]
_2
}
Here you get numbers serialized to the API, but no semantics about what those numbers mean.
If you attempt to add semantics with numerical values:
Gender:
type: integer
format: int32
enum:
- none
- male
- female
You end up with a broken enum:
/// <summary>
/// Defines Gender
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum Gender
{
/// <summary>
/// Enum NUMBER_none for none
/// </summary>
[EnumMember(Value = none)]
NUMBER_none,
/// <summary>
/// Enum NUMBER_male for male
/// </summary>
[EnumMember(Value = male)]
NUMBER_male,
/// <summary>
/// Enum NUMBER_female for female
/// </summary>
[EnumMember(Value = female)]
NUMBER_female
}
Interestingly, the above doesn't cause a parsing issue (type is number, value is non-number).
Sounds like the issue report expects the generator to accept the above definition and have this result in:
/// <summary>
/// Defines Gender
/// </summary>
public enum Gender
{
/// <summary>
/// Enum NUMBER_none for none
/// </summary>
None = 0,
/// <summary>
/// Enum NUMBER_male for male
/// </summary>
Male = 1,
/// <summary>
/// Enum NUMBER_female for female
/// </summary>
Female = 2
}
The problem is: if you look at the OpenAPI spec, it points to: https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.1 for the spec on enum definition and enum validation.
5.5.1. enum
5.5.1.1. Valid values
The value of this keyword MUST be an array. This array MUST have at
least one element. Elements in the array MUST be unique.Elements in the array MAY be of any type, including null.
5.5.1.2. Conditions for successful validation
An instance validates successfully against this keyword if its value
is equal to one of the elements in this keyword's array value.
So, if we accept none,male,female as values in an enum and transform those to 0, 1, 2... not only would this break validation as defined in 5.5.1.2 above, but it would be unintuitive whether the API accepts "0", 0, or none for a specific enum value.
I did a little more investigation and this seems to be a common issue with OpenAPI specification, and is in progress. You can follow the discussion here: OAI/OpenAPI-Specification#681.
We've had this reported on other generators (see #2690), but it's unfortunately a limitation of the specification.
@wing328 should we consider supporting this via vendor extension? That seems a bit hacky to me, but it would work considering the semantics (none, male, female) are only metadata at a code level.
@wing328 should we consider supporting this via vendor extension? That seems a bit hacky to me, but it would work considering the semantics (none, male, female) are only metadata at a code level.
Sorry for late reply on this. Previously I did consider using vendor extension to support this but the one who reported the issue previously was not interested in using vendor extension as a solution.
If there are more demand for a solution addressing this issue, we'll guide the community on how to fix it to begin with.
I have a very similar issue as this one. Therefore, I allow myself to post it in this issue instead of creating an extra issue for something so similar.
Issue
This spec.: https://gist.github.com/larssb/d00e4cf200d85423152df75703d84076 <-- is not interpreted correctly regarding enums. I executed java -jar swagger-codegen-cli-2.2.3.jar generate -i ./octopusDeploy.json -l csharp -o FolderName -c config.json and the config.json file contains {
"packageName": "Octopus.Deploy.API"
} e.g. in the "UserRoleResource.cs" file the enum syntax is /// <summary>
/// Enum _5 for "5"
/// </summary>
[EnumMember(Value = ""5"")]
_5 = "5",
_5 = "5" <-- gives me IDE warnings that [Int] could not be type casted to a [String].Looking forward to hear from you and thank you very much.
@larssb I opened #6887 in an attempt to clean up the differences between string based enums in specs and those integral types that are directly supported by C#. I was wondering if you could take a look?
Most helpful comment
Sorry for late reply on this. Previously I did consider using vendor extension to support this but the one who reported the issue previously was not interested in using vendor extension as a solution.
If there are more demand for a solution addressing this issue, we'll guide the community on how to fix it to begin with.