Skip to content

Commit 56fe7e3

Browse files
authored
[csharp] Fixed duplicate property names (#21206)
* fixed duplicate property names * discard samples * discard samples * added new sample
1 parent ac77339 commit 56fe7e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3604
-5
lines changed

.github/workflows/openapi-generator.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ jobs:
144144
run: |
145145
rm -rf samples/client/petstore/csharp/generichost/latest/HelloWorld
146146
rm -rf samples/client/petstore/csharp/generichost/latest/Tags
147+
rm -rf samples/client/petstore/csharp/generichost/latest/OneOfList
147148
148149
rm -rf samples/client/petstore/csharp/generichost/net8/AllOf
149150
rm -rf samples/client/petstore/csharp/generichost/net8/AnyOf

.github/workflows/samples-dotnet9.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ jobs:
2525
sample:
2626
- samples/client/petstore/csharp/generichost/latest/Tags
2727
- samples/client/petstore/csharp/generichost/latest/HelloWorld
28+
- samples/client/petstore/csharp/generichost/latest/OneOfList
2829
- samples/client/petstore/csharp/generichost/net9/AllOf
2930
- samples/client/petstore/csharp/generichost/net9/AnyOf
3031
- samples/client/petstore/csharp/generichost/net9/AnyOfNoCompare

appveyor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ build_script:
4545
test_script:
4646
- dotnet test samples\client\petstore\csharp\generichost\latest\Tags\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
4747
- dotnet test samples\client\petstore\csharp\generichost\latest\HelloWorld\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
48+
- dotnet test samples\client\petstore\csharp\generichost\latest\OneOfList\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
4849

4950
- dotnet test samples\client\petstore\csharp\generichost\net9\AllOf\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
5051
- dotnet test samples\client\petstore\csharp\generichost\net9\AnyOf\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
generatorName: csharp
2+
outputDir: samples/client/petstore/csharp/generichost/latest/OneOfList
3+
inputSpec: modules/openapi-generator/src/test/resources/bugs/issue_20739.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/csharp
5+
additionalProperties:
6+
packageGuid: '{321C8C3F-0156-40C1-AE42-D59761FB9B6C}'
7+
modelPropertySorting: alphabetical
8+
operationParameterSorting: alphabetical

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

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -625,10 +625,11 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
625625

626626
CodegenComposedSchemas composedSchemas = model.getComposedSchemas();
627627
if (composedSchemas != null) {
628+
Set<String> composedPropertyNames = new HashSet<String>();
628629
List<CodegenProperty> allOf = composedSchemas.getAllOf();
629630
if (allOf != null) {
630631
for (CodegenProperty property : allOf) {
631-
property.name = patchPropertyName(model, camelize(property.baseType));
632+
property.name = patchPropertyName(model, camelize(property.baseType), composedPropertyNames);
632633
patchPropertyVendorExtensions(property);
633634
}
634635
}
@@ -637,7 +638,7 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
637638
if (anyOf != null) {
638639
removePropertiesDeclaredInComposedTypes(objs, model, anyOf);
639640
for (CodegenProperty property : anyOf) {
640-
property.name = patchPropertyName(model, camelize(property.baseType));
641+
property.name = patchPropertyName(model, camelize(property.baseType), composedPropertyNames);
641642
property.isNullable = true;
642643
patchPropertyVendorExtensions(property);
643644
property.vendorExtensions.put("x-base-name", model.name.substring(model.name.lastIndexOf('_') + 1));
@@ -648,7 +649,7 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
648649
if (oneOf != null) {
649650
removePropertiesDeclaredInComposedTypes(objs, model, oneOf);
650651
for (CodegenProperty property : oneOf) {
651-
property.name = patchPropertyName(model, camelize(property.baseType));
652+
property.name = patchPropertyName(model, camelize(property.baseType), composedPropertyNames);
652653
property.isNullable = true;
653654
patchPropertyVendorExtensions(property);
654655
property.vendorExtensions.put("x-base-name", model.name.substring(model.name.lastIndexOf('_') + 1));
@@ -715,13 +716,27 @@ private boolean modelIsMutable(CodegenModel model, Set<String> processed) {
715716
protected void removePropertiesDeclaredInComposedTypes(Map<String, ModelsMap> objs, CodegenModel model, List<CodegenProperty> composedProperties) {
716717
}
717718

718-
private String patchPropertyName(CodegenModel model, String value) {
719+
private String patchPropertyName(CodegenModel model, String value, Set<String> composedPropertyNames) {
719720
String name = escapeReservedWord(model, value);
720721

721722
if (name.startsWith(AbstractCSharpCodegen.invalidParameterNamePrefix)) {
722723
name = AbstractCSharpCodegen.invalidPropertyNamePrefix + name.substring(AbstractCSharpCodegen.invalidParameterNamePrefix.length());
723724
}
724725

726+
// ensure the name we use for a composed property does not already exist as a property or composed property
727+
// only do this if the set of composed property names was provided to ensure this method is idempotent
728+
// we would not calling this method multiple times to result in different values
729+
if (composedPropertyNames != null) {
730+
String tmpName = name;
731+
long count = model.allVars.stream().map(v -> v.name).filter(n -> n.equals(tmpName)).count() + composedPropertyNames.stream().filter(n -> n.equals(tmpName)).count();
732+
733+
if (count > 0) {
734+
name = name + count++;
735+
}
736+
737+
composedPropertyNames.add(name);
738+
}
739+
725740
return name;
726741
}
727742

@@ -753,7 +768,7 @@ protected void patchProperty(Map<String, CodegenModel> enumRefs, CodegenModel mo
753768

754769
patchPropertyVendorExtensions(property);
755770

756-
property.name = patchPropertyName(model, property.name);
771+
property.name = patchPropertyName(model, property.name, null);
757772

758773
String[] nestedTypes = {"List", "Collection", "ICollection", "Dictionary"};
759774

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
openapi: 3.0.1
2+
info:
3+
title: Oneof array test
4+
version: 1.0.0
5+
servers:
6+
- url: /
7+
paths:
8+
/one-of-array:
9+
post:
10+
description: Oneof array test
11+
operationId: oneOfArray
12+
requestBody:
13+
content:
14+
application/json:
15+
schema:
16+
oneOf:
17+
- items:
18+
type: string
19+
type: array
20+
- items:
21+
$ref: '#/components/schemas/TestObject'
22+
type: array
23+
responses:
24+
"204":
25+
description: Successful operation
26+
components:
27+
schemas:
28+
TestObject:
29+
properties:
30+
name:
31+
type: string
32+
type: object

0 commit comments

Comments
 (0)