Skip to content

Commit

Permalink
conditional serialization add only those property which user wants to… (
Browse files Browse the repository at this point in the history
OpenAPITools#9807)

* conditional serialization add only those property which user wants to configure.

* fixed the samples

* fixed the sample String to string issue.

* fixed the sample String to string issue.

* updated the sample

* Added unit test for conditional serialization

* update samples

* remove trailing spaces, update samples

* remove files

* add back files

* build the project in the ci

Co-authored-by: William Cheng <[email protected]>
  • Loading branch information
Ghufz and wing328 authored Jun 29, 2021
1 parent b9b5394 commit 90233d6
Show file tree
Hide file tree
Showing 294 changed files with 39,269 additions and 25 deletions.
4 changes: 4 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ build_script:
- dotnet build samples\client\petstore\csharp-netcore\OpenAPIClient-net47\Org.OpenAPITools.sln
# build C# API client (.net 5.0)
- dotnet build samples\client\petstore\csharp-netcore\OpenAPIClient-net5.0\Org.OpenAPITools.sln
# build C# API client (.net 5.0 with ConditionalSerialization)
- dotnet build samples\client\petstore\csharp-netcore\OpenAPIClient-ConditionalSerialization\Org.OpenAPITools.sln
# build C# API client
- nuget restore samples\client\petstore\csharp\OpenAPIClient\Org.OpenAPITools.sln
- msbuild samples\client\petstore\csharp\OpenAPIClient\Org.OpenAPITools.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
Expand All @@ -80,6 +82,8 @@ test_script:
- dotnet test samples\client\petstore\csharp-netcore\OpenAPIClient-net47\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
# test C# API client (.net 5.0)
- dotnet test samples\client\petstore\csharp-netcore\OpenAPIClient-net5.0\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
# test C# API Client using conditional-serialization
- dotnet test samples\client\petstore\csharp-netcore\OpenAPIClient-ConditionalSerialization\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
# test c# API client
- nunit3-console samples\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\bin\Debug\Org.OpenAPITools.Test.dll --result=myresults.xml;format=AppVeyor
# test c# API client (with PropertyChanged)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# for .net standard
generatorName: csharp-netcore
outputDir: samples/client/petstore/csharp-netcore/OpenAPIClient-ConditionalSerialization
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml
templateDir: modules/openapi-generator/src/main/resources/csharp-netcore
additionalProperties:
packageGuid: '{fa96c953-af24-457d-8a01-f2fd2a7547a9}'
useCompareNetObjects: true
disallowAdditionalPropertiesIfNotPresent: false
useOneOfDiscriminatorLookup: true
targetFramework: netstandard2.0
conditionalSerialization: true
1 change: 1 addition & 0 deletions docs/generators/csharp-netcore.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| ------ | ----------- | ------ | ------- |
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|caseInsensitiveResponseHeaders|Make API response's headers case-insensitive| |false|
|conditionalSerialization|Serialize only those properties which are initialized by user, accepted values are true or false, default value is false.| |false|
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|interfacePrefix|Prefix interfaces with a community standard or widely accepted prefix.| |I|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ public class CodegenConstants {
public static final String OPTIONAL_EMIT_DEFAULT_VALUES = "optionalEmitDefaultValues";
public static final String OPTIONAL_EMIT_DEFAULT_VALUES_DESC = "Set DataMember's EmitDefaultValue.";

public static final String OPTIONAL_CONDITIONAL_SERIALIZATION = "conditionalSerialization";
public static final String OPTIONAL_CONDITIONAL_SERIALIZATION_DESC = "Serialize only those properties which are initialized by user, accepted values are true or false, default value is false.";

public static final String NETCORE_PROJECT_FILE = "netCoreProjectFile";
public static final String NETCORE_PROJECT_FILE_DESC = "Use the new format (.NET Core) for .NET project files (.csproj).";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co

protected boolean optionalAssemblyInfoFlag = true;
protected boolean optionalEmitDefaultValuesFlag = false;
protected boolean conditionalSerialization = false;
protected boolean optionalProjectFileFlag = true;
protected boolean optionalMethodArgumentFlag = true;
protected boolean useDateTimeOffsetFlag = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ public CSharpNetCoreClientCodegen() {
addSwitch(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES,
CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES_DESC,
this.optionalEmitDefaultValuesFlag);

addSwitch(CodegenConstants.OPTIONAL_CONDITIONAL_SERIALIZATION,
CodegenConstants.OPTIONAL_CONDITIONAL_SERIALIZATION_DESC,
this.conditionalSerialization);

addSwitch(CodegenConstants.OPTIONAL_PROJECT_FILE,
CodegenConstants.OPTIONAL_PROJECT_FILE_DESC,
Expand Down Expand Up @@ -570,6 +574,12 @@ public void processOpts() {
additionalProperties.put(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES, optionalEmitDefaultValuesFlag);
}

if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_CONDITIONAL_SERIALIZATION)) {
setConditionalSerialization(convertPropertyToBooleanAndWriteBack(CodegenConstants.OPTIONAL_CONDITIONAL_SERIALIZATION));
} else {
additionalProperties.put(CodegenConstants.OPTIONAL_CONDITIONAL_SERIALIZATION, conditionalSerialization);
}

if (additionalProperties.containsKey(CodegenConstants.MODEL_PROPERTY_NAMING)) {
setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING));
}
Expand Down Expand Up @@ -759,6 +769,10 @@ public void setOptionalEmitDefaultValuesFlag(boolean flag) {
this.optionalEmitDefaultValuesFlag = flag;
}

public void setConditionalSerialization(boolean flag){
this.conditionalSerialization = flag;
}

public void setOptionalProjectFileFlag(boolean flag) {
this.optionalProjectFileFlag = flag;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
{{#description}}
/// <value>{{description}}</value>
{{/description}}
{{^conditionalSerialization}}
[DataMember(Name = "{{baseName}}"{{#required}}, IsRequired = true{{/required}}, EmitDefaultValue = {{#vendorExtensions.x-emit-default-value}}true{{/vendorExtensions.x-emit-default-value}}{{^vendorExtensions.x-emit-default-value}}{{#isBoolean}}true{{/isBoolean}}{{^isBoolean}}{{#isNullable}}true{{/isNullable}}{{^isNullable}}false{{/isNullable}}{{/isBoolean}}{{/vendorExtensions.x-emit-default-value}})]
public {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}} {{name}} { get; set; }
{{#isReadOnly}}
Expand All @@ -44,6 +45,47 @@
return false;
}
{{/isReadOnly}}
{{/conditionalSerialization}}
{{#conditionalSerialization}}
{{#isReadOnly}}
[DataMember(Name = "{{baseName}}"{{#required}}, IsRequired = true{{/required}}, EmitDefaultValue = {{#vendorExtensions.x-emit-default-value}}true{{/vendorExtensions.x-emit-default-value}}{{^vendorExtensions.x-emit-default-value}}{{#isBoolean}}true{{/isBoolean}}{{^isBoolean}}{{#isNullable}}true{{/isNullable}}{{^isNullable}}false{{/isNullable}}{{/isBoolean}}{{/vendorExtensions.x-emit-default-value}})]
public {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}} {{name}} { get; set; }


/// <summary>
/// Returns false as {{name}} should not be serialized given that it's read-only.
/// </summary>
/// <returns>false (boolean)</returns>
public bool ShouldSerialize{{name}}()
{
return false;
}
{{/isReadOnly}}

{{^isReadOnly}}
[DataMember(Name = "{{baseName}}"{{#required}}, IsRequired = true{{/required}}, EmitDefaultValue = {{#vendorExtensions.x-emit-default-value}}true{{/vendorExtensions.x-emit-default-value}}{{^vendorExtensions.x-emit-default-value}}{{#isBoolean}}true{{/isBoolean}}{{^isBoolean}}{{#isNullable}}true{{/isNullable}}{{^isNullable}}false{{/isNullable}}{{/isBoolean}}{{/vendorExtensions.x-emit-default-value}})]
public {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}} {{name}}
{
get{ return _{{name}};}
set
{
_{{name}} = value;
_flag{{name}} = true;
}
}
private {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}} _{{name}};
private bool _flag{{name}};

/// <summary>
/// Returns false as {{name}} should not be serialized given that it's read-only.
/// </summary>
/// <returns>false (boolean)</returns>
public bool ShouldSerialize{{name}}()
{
return _flag{{name}};
}
{{/isReadOnly}}
{{/conditionalSerialization}}
{{/isEnum}}
{{/vars}}
{{#hasRequired}}
Expand Down Expand Up @@ -78,13 +120,24 @@
{{^isInherited}}
{{^isReadOnly}}
{{#required}}
{{^conditionalSerialization}}
{{^vendorExtensions.x-csharp-value-type}}
// to ensure "{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}" is required (not null)
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} ?? throw new ArgumentNullException("{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} is a required property for {{classname}} and cannot be null");
{{/vendorExtensions.x-csharp-value-type}}
{{#vendorExtensions.x-csharp-value-type}}
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
{{/vendorExtensions.x-csharp-value-type}}
{{/conditionalSerialization}}
{{#conditionalSerialization}}
{{^vendorExtensions.x-csharp-value-type}}
// to ensure "{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}" is required (not null)
this._{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} ?? throw new ArgumentNullException("{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} is a required property for {{classname}} and cannot be null");
{{/vendorExtensions.x-csharp-value-type}}
{{#vendorExtensions.x-csharp-value-type}}
this._{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
{{/vendorExtensions.x-csharp-value-type}}
{{/conditionalSerialization}}
{{/required}}
{{/isReadOnly}}
{{/isInherited}}
Expand All @@ -103,7 +156,12 @@
{{/vendorExtensions.x-csharp-value-type}}
{{/defaultValue}}
{{^defaultValue}}
{{^conditionalSerialization}}
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
{{/conditionalSerialization}}
{{#conditionalSerialization}}
this._{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
{{/conditionalSerialization}}
{{/defaultValue}}
{{/required}}
{{/isReadOnly}}
Expand All @@ -121,6 +179,7 @@
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
/// </summary>{{#description}}
/// <value>{{description}}</value>{{/description}}
{{^conditionalSerialization}}
[DataMember(Name = "{{baseName}}"{{#required}}, IsRequired = true{{/required}}, EmitDefaultValue = {{#vendorExtensions.x-emit-default-value}}true{{/vendorExtensions.x-emit-default-value}}{{^vendorExtensions.x-emit-default-value}}{{#isBoolean}}true{{/isBoolean}}{{^isBoolean}}{{#isNullable}}true{{/isNullable}}{{^isNullable}}false{{/isNullable}}{{/isBoolean}}{{/vendorExtensions.x-emit-default-value}})]
{{#isDate}}
[JsonConverter(typeof(OpenAPIDateConverter))]
Expand All @@ -136,8 +195,52 @@
{
return false;
}
{{/isReadOnly}}
{{/conditionalSerialization}}
{{#conditionalSerialization}}
{{#isReadOnly}}
[DataMember(Name = "{{baseName}}"{{#required}}, IsRequired = true{{/required}}, EmitDefaultValue = {{#vendorExtensions.x-emit-default-value}}true{{/vendorExtensions.x-emit-default-value}}{{^vendorExtensions.x-emit-default-value}}{{#isBoolean}}true{{/isBoolean}}{{^isBoolean}}{{#isNullable}}true{{/isNullable}}{{^isNullable}}false{{/isNullable}}{{/isBoolean}}{{/vendorExtensions.x-emit-default-value}})]
{{#isDate}}
[JsonConverter(typeof(OpenAPIDateConverter))]
{{/isDate}}
public {{{dataType}}} {{name}} { get; private set; }

/// <summary>
/// Returns false as {{name}} should not be serialized given that it's read-only.
/// </summary>
/// <returns>false (boolean)</returns>
public bool ShouldSerialize{{name}}()
{
return false;
}
{{/isReadOnly}}
{{^isReadOnly}}
{{#isDate}}
[JsonConverter(typeof(OpenAPIDateConverter))]
{{/isDate}}
[DataMember(Name = "{{baseName}}"{{#required}}, IsRequired = true{{/required}}, EmitDefaultValue = {{#vendorExtensions.x-emit-default-value}}true{{/vendorExtensions.x-emit-default-value}}{{^vendorExtensions.x-emit-default-value}}{{#isBoolean}}true{{/isBoolean}}{{^isBoolean}}{{#isNullable}}true{{/isNullable}}{{^isNullable}}false{{/isNullable}}{{/isBoolean}}{{/vendorExtensions.x-emit-default-value}})]
public {{{dataType}}} {{name}}
{
get{ return _{{name}};}
set
{
_{{name}} = value;
_flag{{name}} = true;
}
}
private {{{dataType}}} _{{name}};
private bool _flag{{name}};

/// <summary>
/// Returns false as {{name}} should not be serialized given that it's read-only.
/// </summary>
/// <returns>false (boolean)</returns>
public bool ShouldSerialize{{name}}()
{
return _flag{{name}};
}
{{/isReadOnly}}
{{/conditionalSerialization}}
{{/isEnum}}
{{/isInherited}}
{{/vars}}
Expand Down
Loading

0 comments on commit 90233d6

Please sign in to comment.