Skip to content

Commit ddb0920

Browse files
authored
Fix C# client enum issue (#774)
* fix csharp enum issue * fix numeric enum value * add docstring to exlain isDataTypeString * fix docstring by adding return * fix ToJson in hash model * remove BaseValidate for map model * restore csproj file
1 parent 21777f2 commit ddb0920

31 files changed

Lines changed: 1316 additions & 79 deletions

modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4577,6 +4577,14 @@ public void generateYAMLSpecFile(Map<String, Object> objs) {
45774577
}
45784578
}
45794579

4580+
/**
4581+
* checks if the data should be classified as "string" in enum
4582+
* e.g. double in C# needs to be double-quoted (e.g. "2.8") by treating it as a string
4583+
* In the future, we may rename this function to "isEnumString"
4584+
*
4585+
* @param dataType data type
4586+
* @return true if it's a enum string
4587+
*/
45804588
public boolean isDataTypeString(String dataType) {
45814589
return "String".equals(dataType);
45824590
}

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,4 +961,10 @@ public String escapeQuotationMark(String input) {
961961
public String escapeUnsafeCharacters(String input) {
962962
return input.replace("*/", "*_/").replace("/*", "/_*").replace("--", "- -");
963963
}
964+
965+
@Override
966+
public boolean isDataTypeString(String dataType) {
967+
// also treat double/decimal/float as "string" in enum so that the values (e.g. 2.8) get double-quoted
968+
return "String".equalsIgnoreCase(dataType) || "double?".equals(dataType) || "decimal?".equals(dataType) || "float?".equals(dataType);
969+
}
964970
}

modules/openapi-generator/src/main/resources/csharp/enumClass.mustache

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
[JsonConverter(typeof(StringEnumConverter))]
88
{{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}
99
{
10-
{{#allowableValues}}{{#enumVars}}
10+
{{#allowableValues}}
11+
{{#enumVars}}
1112
/// <summary>
1213
/// Enum {{name}} for {{{value}}}
1314
/// </summary>
1415
[EnumMember(Value = {{#isLong}}"{{/isLong}}{{#isInteger}}"{{/isInteger}}{{#isFloat}}"{{/isFloat}}{{#isDouble}}"{{/isDouble}}{{{value}}}{{#isLong}}"{{/isLong}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isFloat}}"{{/isFloat}})]
15-
{{name}}{{#isLong}} = {{{value}}}{{/isLong}}{{#isInteger}} = {{{value}}}{{/isInteger}}{{^isInteger}} = {{-index}}{{/isInteger}}{{^-last}},
16-
{{/-last}}{{/enumVars}}{{/allowableValues}}
16+
{{name}}{{#isLong}} = {{{value}}}{{/isLong}}{{#isInteger}} = {{{value}}}{{/isInteger}}{{^isInteger}} = {{-index}}{{/isInteger}}{{^-last}},{{/-last}}
17+
18+
{{/enumVars}}
19+
{{/allowableValues}}
1720
}

modules/openapi-generator/src/main/resources/csharp/modelEnum.mustache

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@
99
{{/isString}}{{/-first}}{{/enumVars}}{{/allowableValues}}
1010
{{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}{{#vendorExtensions.x-enum-byte}}: byte{{/vendorExtensions.x-enum-byte}}
1111
{
12-
{{#allowableValues}}{{#enumVars}}
12+
{{#allowableValues}}
13+
{{#enumVars}}
1314
/// <summary>
1415
/// Enum {{name}} for value: {{{value}}}
1516
/// </summary>
16-
{{#isString}}[EnumMember(Value = "{{{value}}}")]{{/isString}}
17-
{{name}}{{^isString}} = {{{value}}}{{/isString}}{{#isString}} = {{-index}}{{/isString}}{{^-last}},
18-
{{/-last}}{{/enumVars}}{{/allowableValues}}
17+
{{#isString}}
18+
[EnumMember(Value = "{{{value}}}")]
19+
{{/isString}}
20+
{{name}}{{^isString}} = {{{value}}}{{/isString}}{{#isString}} = {{-index}}{{/isString}}{{^-last}},{{/-last}}
21+
22+
{{/enumVars}}
23+
{{/allowableValues}}
1924
}{{! NOTE: This model's enumVars is modified to look like CodegenProperty}}

modules/openapi-generator/src/main/resources/csharp/modelGeneric.mustache

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
133133
/// Returns the JSON string presentation of the object
134134
/// </summary>
135135
/// <returns>JSON string presentation of the object</returns>
136-
public {{#parent}}{{^isArrayModel}}override {{/isArrayModel}}{{/parent}}{{^parent}}virtual {{/parent}}string ToJson()
136+
public {{#parent}}{{^isArrayModel}}{{^isMapModel}}override {{/isMapModel}}{{/isArrayModel}}{{/parent}}{{^parent}}virtual {{/parent}}string ToJson()
137137
{
138138
return JsonConvert.SerializeObject(this, Formatting.Indented);
139139
}
@@ -247,7 +247,9 @@ this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
247247
{{/discriminator}}
248248
{{#parent}}
249249
{{^isArrayModel}}
250+
{{^isMapModel}}
250251
foreach(var x in BaseValidate(validationContext)) yield return x;
252+
{{/isMapModel}}
251253
{{/isArrayModel}}
252254
{{/parent}}
253255
{{#vars}}

modules/openapi-generator/src/main/resources/csharp/modelInnerEnum.mustache

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@
1010
{{/isString}}
1111
{{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}{{#vendorExtensions.x-enum-byte}}: byte{{/vendorExtensions.x-enum-byte}}
1212
{
13-
{{#allowableValues}}{{#enumVars}}
13+
{{#allowableValues}}
14+
{{#enumVars}}
1415
/// <summary>
1516
/// Enum {{name}} for value: {{{value}}}
1617
/// </summary>
17-
{{#isString}}[EnumMember(Value = "{{{value}}}")]{{/isString}}
18-
{{name}}{{^isString}} = {{{value}}}{{/isString}}{{#isString}} = {{-index}}{{/isString}}{{^-last}},
19-
{{/-last}}{{/enumVars}}{{/allowableValues}}
18+
{{#isString}}
19+
[EnumMember(Value = "{{{value}}}")]
20+
{{/isString}}
21+
{{name}}{{^isString}} = {{{value}}}{{/isString}}{{#isString}} = {{-index}}{{/isString}}{{^-last}},{{/-last}}
22+
23+
{{/enumVars}}
24+
{{/allowableValues}}
2025
}
2126
{{/isContainer}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.0.0-SNAPSHOT
1+
3.2.1-SNAPSHOT

samples/client/petstore/csharp/OpenAPIClient/README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ namespace Example
7676
try
7777
{
7878
// To test special tags
79-
ModelClient result = apiInstance.TestSpecialTags(modelClient);
79+
ModelClient result = apiInstance.Call123TestSpecialTags(modelClient);
8080
Debug.WriteLine(result);
8181
}
8282
catch (Exception e)
8383
{
84-
Debug.Print("Exception when calling AnotherFakeApi.TestSpecialTags: " + e.Message );
84+
Debug.Print("Exception when calling AnotherFakeApi.Call123TestSpecialTags: " + e.Message );
8585
}
8686

8787
}
@@ -96,11 +96,12 @@ All URIs are relative to *http://petstore.swagger.io:80/v2*
9696

9797
Class | Method | HTTP request | Description
9898
------------ | ------------- | ------------- | -------------
99-
*AnotherFakeApi* | [**TestSpecialTags**](docs/AnotherFakeApi.md#testspecialtags) | **PATCH** /another-fake/dummy | To test special tags
99+
*AnotherFakeApi* | [**Call123TestSpecialTags**](docs/AnotherFakeApi.md#call123testspecialtags) | **PATCH** /another-fake/dummy | To test special tags
100100
*FakeApi* | [**FakeOuterBooleanSerialize**](docs/FakeApi.md#fakeouterbooleanserialize) | **POST** /fake/outer/boolean |
101101
*FakeApi* | [**FakeOuterCompositeSerialize**](docs/FakeApi.md#fakeoutercompositeserialize) | **POST** /fake/outer/composite |
102102
*FakeApi* | [**FakeOuterNumberSerialize**](docs/FakeApi.md#fakeouternumberserialize) | **POST** /fake/outer/number |
103103
*FakeApi* | [**FakeOuterStringSerialize**](docs/FakeApi.md#fakeouterstringserialize) | **POST** /fake/outer/string |
104+
*FakeApi* | [**TestBodyWithFileSchema**](docs/FakeApi.md#testbodywithfileschema) | **PUT** /fake/body-with-file-schema |
104105
*FakeApi* | [**TestBodyWithQueryParams**](docs/FakeApi.md#testbodywithqueryparams) | **PUT** /fake/body-with-query-params |
105106
*FakeApi* | [**TestClientModel**](docs/FakeApi.md#testclientmodel) | **PATCH** /fake | To test \"client\" model
106107
*FakeApi* | [**TestEndpointParameters**](docs/FakeApi.md#testendpointparameters) | **POST** /fake | Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
@@ -116,6 +117,7 @@ Class | Method | HTTP request | Description
116117
*PetApi* | [**UpdatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet
117118
*PetApi* | [**UpdatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data
118119
*PetApi* | [**UploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image
120+
*PetApi* | [**UploadFileWithRequiredFile**](docs/PetApi.md#uploadfilewithrequiredfile) | **POST** /fake/{petId}/uploadImageWithRequiredFile | uploads an image (required)
119121
*StoreApi* | [**DeleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{order_id} | Delete purchase order by ID
120122
*StoreApi* | [**GetInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status
121123
*StoreApi* | [**GetOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{order_id} | Find purchase order by ID
@@ -148,6 +150,8 @@ Class | Method | HTTP request | Description
148150
- [Model.EnumArrays](docs/EnumArrays.md)
149151
- [Model.EnumClass](docs/EnumClass.md)
150152
- [Model.EnumTest](docs/EnumTest.md)
153+
- [Model.File](docs/File.md)
154+
- [Model.FileSchemaTestClass](docs/FileSchemaTestClass.md)
151155
- [Model.FormatTest](docs/FormatTest.md)
152156
- [Model.HasOnlyReadOnly](docs/HasOnlyReadOnly.md)
153157
- [Model.List](docs/List.md)
@@ -164,6 +168,7 @@ Class | Method | HTTP request | Description
164168
- [Model.ReadOnlyFirst](docs/ReadOnlyFirst.md)
165169
- [Model.Return](docs/Return.md)
166170
- [Model.SpecialModelName](docs/SpecialModelName.md)
171+
- [Model.StringBooleanMap](docs/StringBooleanMap.md)
167172
- [Model.Tag](docs/Tag.md)
168173
- [Model.User](docs/User.md)
169174

samples/client/petstore/csharp/OpenAPIClient/docs/AnotherFakeApi.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ All URIs are relative to *http://petstore.swagger.io:80/v2*
44

55
Method | HTTP request | Description
66
------------- | ------------- | -------------
7-
[**TestSpecialTags**](AnotherFakeApi.md#testspecialtags) | **PATCH** /another-fake/dummy | To test special tags
7+
[**Call123TestSpecialTags**](AnotherFakeApi.md#call123testspecialtags) | **PATCH** /another-fake/dummy | To test special tags
88

99

10-
<a name="testspecialtags"></a>
11-
# **TestSpecialTags**
12-
> ModelClient TestSpecialTags (ModelClient modelClient)
10+
<a name="call123testspecialtags"></a>
11+
# **Call123TestSpecialTags**
12+
> ModelClient Call123TestSpecialTags (ModelClient modelClient)
1313
1414
To test special tags
1515

16-
To test special tags
16+
To test special tags and operation ID starting with number
1717

1818
### Example
1919
```csharp
@@ -25,7 +25,7 @@ using Org.OpenAPITools.Model;
2525

2626
namespace Example
2727
{
28-
public class TestSpecialTagsExample
28+
public class Call123TestSpecialTagsExample
2929
{
3030
public void main()
3131
{
@@ -35,12 +35,12 @@ namespace Example
3535
try
3636
{
3737
// To test special tags
38-
ModelClient result = apiInstance.TestSpecialTags(modelClient);
38+
ModelClient result = apiInstance.Call123TestSpecialTags(modelClient);
3939
Debug.WriteLine(result);
4040
}
4141
catch (Exception e)
4242
{
43-
Debug.Print("Exception when calling AnotherFakeApi.TestSpecialTags: " + e.Message );
43+
Debug.Print("Exception when calling AnotherFakeApi.Call123TestSpecialTags: " + e.Message );
4444
}
4545
}
4646
}

samples/client/petstore/csharp/OpenAPIClient/docs/FakeApi.md

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Method | HTTP request | Description
88
[**FakeOuterCompositeSerialize**](FakeApi.md#fakeoutercompositeserialize) | **POST** /fake/outer/composite |
99
[**FakeOuterNumberSerialize**](FakeApi.md#fakeouternumberserialize) | **POST** /fake/outer/number |
1010
[**FakeOuterStringSerialize**](FakeApi.md#fakeouterstringserialize) | **POST** /fake/outer/string |
11+
[**TestBodyWithFileSchema**](FakeApi.md#testbodywithfileschema) | **PUT** /fake/body-with-file-schema |
1112
[**TestBodyWithQueryParams**](FakeApi.md#testbodywithqueryparams) | **PUT** /fake/body-with-query-params |
1213
[**TestClientModel**](FakeApi.md#testclientmodel) | **PATCH** /fake | To test \&quot;client\&quot; model
1314
[**TestEndpointParameters**](FakeApi.md#testendpointparameters) | **POST** /fake | Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
@@ -256,6 +257,65 @@ No authorization required
256257

257258
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
258259

260+
<a name="testbodywithfileschema"></a>
261+
# **TestBodyWithFileSchema**
262+
> void TestBodyWithFileSchema (FileSchemaTestClass fileSchemaTestClass)
263+
264+
265+
266+
For this test, the body for this request much reference a schema named `File`.
267+
268+
### Example
269+
```csharp
270+
using System;
271+
using System.Diagnostics;
272+
using Org.OpenAPITools.Api;
273+
using Org.OpenAPITools.Client;
274+
using Org.OpenAPITools.Model;
275+
276+
namespace Example
277+
{
278+
public class TestBodyWithFileSchemaExample
279+
{
280+
public void main()
281+
{
282+
var apiInstance = new FakeApi();
283+
var fileSchemaTestClass = new FileSchemaTestClass(); // FileSchemaTestClass |
284+
285+
try
286+
{
287+
apiInstance.TestBodyWithFileSchema(fileSchemaTestClass);
288+
}
289+
catch (Exception e)
290+
{
291+
Debug.Print("Exception when calling FakeApi.TestBodyWithFileSchema: " + e.Message );
292+
}
293+
}
294+
}
295+
}
296+
```
297+
298+
### Parameters
299+
300+
Name | Type | Description | Notes
301+
------------- | ------------- | ------------- | -------------
302+
**fileSchemaTestClass** | [**FileSchemaTestClass**](FileSchemaTestClass.md)| |
303+
304+
### Return type
305+
306+
void (empty response body)
307+
308+
### Authorization
309+
310+
No authorization required
311+
312+
### HTTP request headers
313+
314+
- **Content-Type**: application/json
315+
- **Accept**: Not defined
316+
317+
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
318+
259319
<a name="testbodywithqueryparams"></a>
260320
# **TestBodyWithQueryParams**
261321
> void TestBodyWithQueryParams (string query, User user)
@@ -495,7 +555,7 @@ namespace Example
495555
var enumQueryString = enumQueryString_example; // string | Query parameter enum test (string) (optional) (default to -efg)
496556
var enumQueryInteger = 56; // int? | Query parameter enum test (double) (optional)
497557
var enumQueryDouble = 1.2; // double? | Query parameter enum test (double) (optional)
498-
var enumFormStringArray = enumFormStringArray_example; // List<string> | Form parameter enum test (string array) (optional) (default to $)
558+
var enumFormStringArray = new List<string>(); // List<string> | Form parameter enum test (string array) (optional) (default to $)
499559
var enumFormString = enumFormString_example; // string | Form parameter enum test (string) (optional) (default to -efg)
500560
501561
try
@@ -522,7 +582,7 @@ Name | Type | Description | Notes
522582
**enumQueryString** | **string**| Query parameter enum test (string) | [optional] [default to -efg]
523583
**enumQueryInteger** | **int?**| Query parameter enum test (double) | [optional]
524584
**enumQueryDouble** | **double?**| Query parameter enum test (double) | [optional]
525-
**enumFormStringArray** | **List&lt;string&gt;**| Form parameter enum test (string array) | [optional] [default to $]
585+
**enumFormStringArray** | [**List&lt;string&gt;**](string.md)| Form parameter enum test (string array) | [optional] [default to $]
526586
**enumFormString** | **string**| Form parameter enum test (string) | [optional] [default to -efg]
527587

528588
### Return type

0 commit comments

Comments
 (0)