forked from loafle/openapi-generator-original
Merge remote-tracking branch 'origin/master' into okhttp-gson-next-gen-better-error
This commit is contained in:
commit
b970f60c0c
3
.github/workflows/samples-kotlin.yaml
vendored
3
.github/workflows/samples-kotlin.yaml
vendored
@ -30,8 +30,7 @@ jobs:
|
||||
#- samples/client/petstore/kotlin-json-request-string
|
||||
- samples/client/petstore/kotlin-jvm-okhttp4-coroutines
|
||||
- samples/client/petstore/kotlin-moshi-codegen
|
||||
# need some special setup
|
||||
#- samples/client/petstore/kotlin-multiplatform
|
||||
- samples/client/petstore/kotlin-multiplatform
|
||||
- samples/client/petstore/kotlin-nonpublic
|
||||
- samples/client/petstore/kotlin-nullable
|
||||
- samples/client/petstore/kotlin-okhttp3
|
||||
|
24
README.md
24
README.md
@ -223,21 +223,21 @@ Examples:
|
||||
# Execute latest released openapi-generator-cli
|
||||
openapi-generator-cli version
|
||||
|
||||
# Execute version 3.1.0 for the current invocation, regardless of the latest released version
|
||||
OPENAPI_GENERATOR_VERSION=3.1.0 openapi-generator-cli version
|
||||
# Execute version 4.1.0 for the current invocation, regardless of the latest released version
|
||||
OPENAPI_GENERATOR_VERSION=4.1.0 openapi-generator-cli version
|
||||
|
||||
# Execute version 3.1.0-SNAPSHOT for the current invocation
|
||||
OPENAPI_GENERATOR_VERSION=3.1.0-SNAPSHOT openapi-generator-cli version
|
||||
# Execute version 4.1.0-SNAPSHOT for the current invocation
|
||||
OPENAPI_GENERATOR_VERSION=4.1.0-SNAPSHOT openapi-generator-cli version
|
||||
|
||||
# Execute version 3.0.2 for every invocation in the current shell session
|
||||
export OPENAPI_GENERATOR_VERSION=3.0.2
|
||||
openapi-generator-cli version # is 3.0.2
|
||||
openapi-generator-cli version # is also 3.0.2
|
||||
# Execute version 4.0.2 for every invocation in the current shell session
|
||||
export OPENAPI_GENERATOR_VERSION=4.0.2
|
||||
openapi-generator-cli version # is 4.0.2
|
||||
openapi-generator-cli version # is also 4.0.2
|
||||
|
||||
# To "install" a specific version, set the variable in .bashrc/.bash_profile
|
||||
echo "export OPENAPI_GENERATOR_VERSION=3.0.2" >> ~/.bashrc
|
||||
echo "export OPENAPI_GENERATOR_VERSION=4.0.2" >> ~/.bashrc
|
||||
source ~/.bashrc
|
||||
openapi-generator-cli version # is always 3.0.2, unless any of the above overrides are done ad hoc
|
||||
openapi-generator-cli version # is always 4.0.2, unless any of the above overrides are done ad hoc
|
||||
```
|
||||
|
||||
### [1.4 - Build Projects](#table-of-contents)
|
||||
@ -844,6 +844,8 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
|
||||
- 2021-10-02 - [How to Write Fewer Lines of Code with the OpenAPI Generator](https://hackernoon.com/how-to-write-fewer-lines-of-code-with-the-openapi-generator) by [Mikhail Alfa](https://hackernoon.com/u/alphamikle)
|
||||
- 2021-10-12 - [OpenAPI Generator : 4000 étoiles sur GitHub et des spaghettis](https://www.youtube.com/watch?v=9hEsNBSqTFk) by [Jérémie Bresson](https://github.com/jmini) at [Devoxx FR 2021](https://cfp.devoxx.fr/2021/speaker/jeremie_bresson)
|
||||
- 2021-10-17 - [Generate a TypeScript HTTP Client From An OpenAPI Spec In DotNET 5](https://richardwillis.info/blog/generate-a-type-script-http-client-from-an-open-api-spec-in-dot-net-5) by [Richard Willis](https://github.com/badsyntax)
|
||||
- 2021-11-06 - [スタートアップの開発で意識したこと](https://zenn.dev/woo_noo/articles/5cb09f8e2899ae782ad1) by [woo-noo](https://zenn.dev/woo_noo)
|
||||
- 2021-11-09 - [Effective Software Development using OpenAPI Generator](https://apexlabs.ai/post/effective-software-development-using-openapi-generator) by Ajil Oomme
|
||||
|
||||
## [6 - About Us](#table-of-contents)
|
||||
|
||||
@ -1060,7 +1062,7 @@ If you want to join the committee, please kindly apply by sending an email to te
|
||||
| GraphQL | @renepardon (2018/12) |
|
||||
| Groovy | |
|
||||
| Haskell | |
|
||||
| Java | @bbdouglas (2017/07) @sreeshas (2017/08) @jfiala (2017/08) @lukoyanov (2017/09) @cbornet (2017/09) @jeff9finger (2018/01) @karismann (2019/03) @Zomzog (2019/04) @lwlee2608 (2019/10) @nmuesch (2021/01) |
|
||||
| Java | @bbdouglas (2017/07) @sreeshas (2017/08) @jfiala (2017/08) @lukoyanov (2017/09) @cbornet (2017/09) @jeff9finger (2018/01) @karismann (2019/03) @Zomzog (2019/04) @lwlee2608 (2019/10) |
|
||||
| JMeter | @kannkyo (2021/01) |
|
||||
| Kotlin | @jimschubert (2017/09) [:heart:](https://www.patreon.com/jimschubert), @dr4ke616 (2018/08) @karismann (2019/03) @Zomzog (2019/04) @andrewemery (2019/10) @4brunu (2019/11) @yutaka0m (2020/03) |
|
||||
| Lua | @daurnimator (2017/08) |
|
||||
|
12
bin/configs/swift5-frozenEnums.yaml
Normal file
12
bin/configs/swift5-frozenEnums.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
generatorName: swift5
|
||||
outputDir: samples/client/petstore/swift5/frozenEnums
|
||||
inputSpec: modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/swift5
|
||||
generateAliasAsModel: true
|
||||
additionalProperties:
|
||||
podAuthors: ""
|
||||
podSummary: PetstoreClient
|
||||
sortParamsByRequiredFlag: false
|
||||
generateFrozenEnums: false
|
||||
projectName: PetstoreClient
|
||||
podHomepage: https://github.com/openapitools/openapi-generator
|
@ -0,0 +1,11 @@
|
||||
generatorName: typescript-angular
|
||||
outputDir: samples/client/petstore/typescript-angular-v13-provided-in-root/builds/with-npm
|
||||
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
|
||||
additionalProperties:
|
||||
ngVersion: 13.0.1
|
||||
npmVersion: 1.0.0
|
||||
npmName: '@openapitools/typescript-angular-petstore'
|
||||
npmRepository: https://skimdb.npmjs.com/registry
|
||||
snapshot: false
|
||||
supportsES6: true
|
7
bin/configs/typescript-angular-v13-provided-in-root.yaml
Normal file
7
bin/configs/typescript-angular-v13-provided-in-root.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
generatorName: typescript-angular
|
||||
outputDir: samples/client/petstore/typescript-angular-v13-provided-in-root/builds/default
|
||||
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
|
||||
additionalProperties:
|
||||
ngVersion: 13.0.1
|
||||
supportsES6: true
|
@ -86,6 +86,7 @@ The following generators are available:
|
||||
* [cpp-qt-qhttpengine-server](generators/cpp-qt-qhttpengine-server.md)
|
||||
* [cpp-restbed-server](generators/cpp-restbed-server.md)
|
||||
* [csharp-nancyfx](generators/csharp-nancyfx.md)
|
||||
* [csharp-netcore-functions](generators/csharp-netcore-functions.md)
|
||||
* [erlang-server](generators/erlang-server.md)
|
||||
* [fsharp-functions (beta)](generators/fsharp-functions.md)
|
||||
* [fsharp-giraffe-server (beta)](generators/fsharp-giraffe-server.md)
|
||||
|
300
docs/generators/csharp-netcore-functions.md
Normal file
300
docs/generators/csharp-netcore-functions.md
Normal file
@ -0,0 +1,300 @@
|
||||
---
|
||||
title: Config Options for csharp-netcore-functions
|
||||
sidebar_label: csharp-netcore-functions
|
||||
---
|
||||
|
||||
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
|
||||
|
||||
| Option | Description | Values | Default |
|
||||
| ------ | ----------- | ------ | ------- |
|
||||
|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|
|
||||
|library|HTTP library template (sub-template) to use|<dl><dt>**httpclient**</dt><dd>HttpClient (https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient) (Experimental. May subject to breaking changes without further notice.)</dd><dt>**restsharp**</dt><dd>RestSharp (https://github.com/restsharp/RestSharp)</dd></dl>|restsharp|
|
||||
|licenseId|The identifier of the license| |null|
|
||||
|modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |PascalCase|
|
||||
|netCoreProjectFile|Use the new format (.NET Core) for .NET project files (.csproj).| |false|
|
||||
|nonPublicApi|Generates code with reduced access modifiers; allows embedding elsewhere without exposing non-public API calls to consumers.| |false|
|
||||
|nullableReferenceTypes|Use nullable annotations in the project. Only supported on C# 8 / ASP.NET Core 3.0 or newer.| |false|
|
||||
|optionalAssemblyInfo|Generate AssemblyInfo.cs.| |true|
|
||||
|optionalEmitDefaultValues|Set DataMember's EmitDefaultValue.| |false|
|
||||
|optionalMethodArgument|C# Optional method argument, e.g. void square(int x=10) (.net 4.0+ only).| |true|
|
||||
|optionalProjectFile|Generate {PackageName}.csproj.| |true|
|
||||
|packageGuid|The GUID that will be associated with the C# project| |null|
|
||||
|packageName|C# package name (convention: Title.Case).| |Org.OpenAPITools|
|
||||
|packageTags|Tags to identify the package| |null|
|
||||
|packageVersion|C# package version.| |1.0.0|
|
||||
|releaseNote|Release note, default to 'Minor update'.| |Minor update|
|
||||
|returnICollection|Return ICollection<T> instead of the concrete type.| |false|
|
||||
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|
||||
|sourceFolder|source folder for generated code| |src|
|
||||
|targetFramework|The target .NET framework version. To target multiple frameworks, use `;` as the separator, e.g. `netstandard2.1;netcoreapp3.0`|<dl><dt>**netstandard1.3**</dt><dd>.NET Standard 1.3 compatible</dd><dt>**netstandard1.4**</dt><dd>.NET Standard 1.4 compatible</dd><dt>**netstandard1.5**</dt><dd>.NET Standard 1.5 compatible</dd><dt>**netstandard1.6**</dt><dd>.NET Standard 1.6 compatible</dd><dt>**netstandard2.0**</dt><dd>.NET Standard 2.0 compatible</dd><dt>**netstandard2.1**</dt><dd>.NET Standard 2.1 compatible</dd><dt>**netcoreapp2.0**</dt><dd>.NET Core 2.0 compatible</dd><dt>**netcoreapp2.1**</dt><dd>.NET Core 2.1 compatible</dd><dt>**netcoreapp3.0**</dt><dd>.NET Core 3.0 compatible</dd><dt>**netcoreapp3.1**</dt><dd>.NET Core 3.1 compatible</dd><dt>**net47**</dt><dd>.NET Framework 4.7 compatible</dd><dt>**net5.0**</dt><dd>.NET 5.0 compatible</dd></dl>|netstandard2.0|
|
||||
|useCollection|Deserialize array types to Collection<T> instead of List<T>.| |false|
|
||||
|useDateTimeOffset|Use DateTimeOffset to model date-time properties| |false|
|
||||
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped.| |false|
|
||||
|validatable|Generates self-validatable models.| |true|
|
||||
|
||||
## IMPORT MAPPING
|
||||
|
||||
| Type/Alias | Imports |
|
||||
| ---------- | ------- |
|
||||
|
||||
|
||||
## INSTANTIATION TYPES
|
||||
|
||||
| Type/Alias | Instantiated By |
|
||||
| ---------- | --------------- |
|
||||
|array|List|
|
||||
|list|List|
|
||||
|map|Dictionary|
|
||||
|
||||
|
||||
## LANGUAGE PRIMITIVES
|
||||
|
||||
<ul class="column-ul">
|
||||
<li>Boolean</li>
|
||||
<li>Collection</li>
|
||||
<li>DateTime</li>
|
||||
<li>DateTime?</li>
|
||||
<li>DateTimeOffset</li>
|
||||
<li>DateTimeOffset?</li>
|
||||
<li>Decimal</li>
|
||||
<li>Dictionary</li>
|
||||
<li>Double</li>
|
||||
<li>Float</li>
|
||||
<li>Guid</li>
|
||||
<li>Guid?</li>
|
||||
<li>ICollection</li>
|
||||
<li>Int32</li>
|
||||
<li>Int64</li>
|
||||
<li>List</li>
|
||||
<li>Object</li>
|
||||
<li>String</li>
|
||||
<li>System.IO.Stream</li>
|
||||
<li>bool</li>
|
||||
<li>bool?</li>
|
||||
<li>byte[]</li>
|
||||
<li>decimal</li>
|
||||
<li>decimal?</li>
|
||||
<li>double</li>
|
||||
<li>double?</li>
|
||||
<li>float</li>
|
||||
<li>float?</li>
|
||||
<li>int</li>
|
||||
<li>int?</li>
|
||||
<li>long</li>
|
||||
<li>long?</li>
|
||||
<li>string</li>
|
||||
</ul>
|
||||
|
||||
## RESERVED WORDS
|
||||
|
||||
<ul class="column-ul">
|
||||
<li>Client</li>
|
||||
<li>Configuration</li>
|
||||
<li>Version</li>
|
||||
<li>abstract</li>
|
||||
<li>as</li>
|
||||
<li>base</li>
|
||||
<li>bool</li>
|
||||
<li>break</li>
|
||||
<li>byte</li>
|
||||
<li>case</li>
|
||||
<li>catch</li>
|
||||
<li>char</li>
|
||||
<li>checked</li>
|
||||
<li>class</li>
|
||||
<li>client</li>
|
||||
<li>const</li>
|
||||
<li>continue</li>
|
||||
<li>decimal</li>
|
||||
<li>default</li>
|
||||
<li>delegate</li>
|
||||
<li>do</li>
|
||||
<li>double</li>
|
||||
<li>else</li>
|
||||
<li>enum</li>
|
||||
<li>event</li>
|
||||
<li>explicit</li>
|
||||
<li>extern</li>
|
||||
<li>false</li>
|
||||
<li>finally</li>
|
||||
<li>fixed</li>
|
||||
<li>float</li>
|
||||
<li>for</li>
|
||||
<li>foreach</li>
|
||||
<li>goto</li>
|
||||
<li>if</li>
|
||||
<li>implicit</li>
|
||||
<li>in</li>
|
||||
<li>int</li>
|
||||
<li>interface</li>
|
||||
<li>internal</li>
|
||||
<li>is</li>
|
||||
<li>localVarFileParams</li>
|
||||
<li>localVarFormParams</li>
|
||||
<li>localVarHeaderParams</li>
|
||||
<li>localVarHttpContentType</li>
|
||||
<li>localVarHttpContentTypes</li>
|
||||
<li>localVarHttpHeaderAccept</li>
|
||||
<li>localVarHttpHeaderAccepts</li>
|
||||
<li>localVarPath</li>
|
||||
<li>localVarPathParams</li>
|
||||
<li>localVarPostBody</li>
|
||||
<li>localVarQueryParams</li>
|
||||
<li>localVarResponse</li>
|
||||
<li>localVarStatusCode</li>
|
||||
<li>lock</li>
|
||||
<li>long</li>
|
||||
<li>namespace</li>
|
||||
<li>new</li>
|
||||
<li>null</li>
|
||||
<li>object</li>
|
||||
<li>operator</li>
|
||||
<li>out</li>
|
||||
<li>override</li>
|
||||
<li>parameter</li>
|
||||
<li>params</li>
|
||||
<li>private</li>
|
||||
<li>protected</li>
|
||||
<li>public</li>
|
||||
<li>readonly</li>
|
||||
<li>ref</li>
|
||||
<li>return</li>
|
||||
<li>sbyte</li>
|
||||
<li>sealed</li>
|
||||
<li>short</li>
|
||||
<li>sizeof</li>
|
||||
<li>stackalloc</li>
|
||||
<li>static</li>
|
||||
<li>string</li>
|
||||
<li>struct</li>
|
||||
<li>switch</li>
|
||||
<li>this</li>
|
||||
<li>throw</li>
|
||||
<li>true</li>
|
||||
<li>try</li>
|
||||
<li>typeof</li>
|
||||
<li>uint</li>
|
||||
<li>ulong</li>
|
||||
<li>unchecked</li>
|
||||
<li>unsafe</li>
|
||||
<li>ushort</li>
|
||||
<li>using</li>
|
||||
<li>virtual</li>
|
||||
<li>void</li>
|
||||
<li>volatile</li>
|
||||
<li>while</li>
|
||||
</ul>
|
||||
|
||||
## FEATURE SET
|
||||
|
||||
|
||||
### Client Modification Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|BasePath|✓|ToolingExtension
|
||||
|Authorizations|✗|ToolingExtension
|
||||
|UserAgent|✓|ToolingExtension
|
||||
|MockServer|✗|ToolingExtension
|
||||
|
||||
### Data Type Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Custom|✗|OAS2,OAS3
|
||||
|Int32|✓|OAS2,OAS3
|
||||
|Int64|✓|OAS2,OAS3
|
||||
|Float|✓|OAS2,OAS3
|
||||
|Double|✓|OAS2,OAS3
|
||||
|Decimal|✓|ToolingExtension
|
||||
|String|✓|OAS2,OAS3
|
||||
|Byte|✓|OAS2,OAS3
|
||||
|Binary|✓|OAS2,OAS3
|
||||
|Boolean|✓|OAS2,OAS3
|
||||
|Date|✓|OAS2,OAS3
|
||||
|DateTime|✓|OAS2,OAS3
|
||||
|Password|✓|OAS2,OAS3
|
||||
|File|✓|OAS2
|
||||
|Array|✓|OAS2,OAS3
|
||||
|Maps|✓|ToolingExtension
|
||||
|CollectionFormat|✓|OAS2
|
||||
|CollectionFormatMulti|✓|OAS2
|
||||
|Enum|✓|OAS2,OAS3
|
||||
|ArrayOfEnum|✓|ToolingExtension
|
||||
|ArrayOfModel|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfModel|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|
||||
|MapOfEnum|✓|ToolingExtension
|
||||
|MapOfModel|✓|ToolingExtension
|
||||
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|
||||
|MapOfCollectionOfModel|✓|ToolingExtension
|
||||
|MapOfCollectionOfEnum|✓|ToolingExtension
|
||||
|
||||
### Documentation Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Readme|✓|ToolingExtension
|
||||
|Model|✓|ToolingExtension
|
||||
|Api|✓|ToolingExtension
|
||||
|
||||
### Global Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Host|✓|OAS2,OAS3
|
||||
|BasePath|✓|OAS2,OAS3
|
||||
|Info|✓|OAS2,OAS3
|
||||
|Schemes|✗|OAS2,OAS3
|
||||
|PartialSchemes|✓|OAS2,OAS3
|
||||
|Consumes|✓|OAS2
|
||||
|Produces|✓|OAS2
|
||||
|ExternalDocumentation|✓|OAS2,OAS3
|
||||
|Examples|✓|OAS2,OAS3
|
||||
|XMLStructureDefinitions|✗|OAS2,OAS3
|
||||
|MultiServer|✗|OAS3
|
||||
|ParameterizedServer|✗|OAS3
|
||||
|ParameterStyling|✗|OAS3
|
||||
|Callbacks|✗|OAS3
|
||||
|LinkObjects|✗|OAS3
|
||||
|
||||
### Parameter Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Path|✓|OAS2,OAS3
|
||||
|Query|✓|OAS2,OAS3
|
||||
|Header|✓|OAS2,OAS3
|
||||
|Body|✓|OAS2
|
||||
|FormUnencoded|✓|OAS2
|
||||
|FormMultipart|✓|OAS2
|
||||
|Cookie|✓|OAS3
|
||||
|
||||
### Schema Support Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Simple|✓|OAS2,OAS3
|
||||
|Composite|✓|OAS2,OAS3
|
||||
|Polymorphism|✓|OAS2,OAS3
|
||||
|Union|✗|OAS3
|
||||
|
||||
### Security Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|BasicAuth|✓|OAS2,OAS3
|
||||
|ApiKey|✓|OAS2,OAS3
|
||||
|OpenIDConnect|✗|OAS3
|
||||
|BearerToken|✗|OAS3
|
||||
|OAuth2_Implicit|✓|OAS2,OAS3
|
||||
|OAuth2_Password|✗|OAS2,OAS3
|
||||
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|
||||
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
|
||||
|
||||
### Wire Format Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|JSON|✓|OAS2,OAS3
|
||||
|XML|✓|OAS2,OAS3
|
||||
|PROTOBUF|✗|ToolingExtension
|
||||
|Custom|✗|OAS2,OAS3
|
@ -11,6 +11,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|apiNamePrefix|Prefix that will be appended to all API names ('tags'). Default: empty string. e.g. Pet => Pet.| |null|
|
||||
|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|
|
||||
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|
||||
|generateFrozenEnums|Generate frozen enums (default: true)| |true|
|
||||
|generateModelAdditionalProperties|Generate model additional properties (default: true)| |true|
|
||||
|hashableModels|Make hashable models (default: true)| |true|
|
||||
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|
||||
|
@ -19,7 +19,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|modelFileSuffix|The suffix of the file of the generated model (model<suffix>.ts).| |null|
|
||||
|modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name. Only change it if you provide your own run-time code for (de-)serialization of models| |original|
|
||||
|modelSuffix|The suffix of the generated model.| |null|
|
||||
|ngVersion|The version of Angular. (At least 6.0.0)| |12.2.12|
|
||||
|ngVersion|The version of Angular. (At least 6.0.0)| |13.0.1|
|
||||
|npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null|
|
||||
|npmRepository|Use this property to set an url your private npmRepo in the package.json| |null|
|
||||
|npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0|
|
||||
|
@ -29,7 +29,8 @@ public class CodegenOperation {
|
||||
isArray, isMultipart,
|
||||
isResponseBinary = false, isResponseFile = false, hasReference = false,
|
||||
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
|
||||
isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false;
|
||||
isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false,
|
||||
hasErrorResponseObject; // if 4xx, 5xx repsonses have at least one error object defined
|
||||
public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType,
|
||||
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
|
||||
public CodegenDiscriminator discriminator;
|
||||
@ -297,6 +298,7 @@ public class CodegenOperation {
|
||||
sb.append(", isResponseFile=").append(isResponseFile);
|
||||
sb.append(", hasReference=").append(hasReference);
|
||||
sb.append(", hasDefaultResponse=").append(hasDefaultResponse);
|
||||
sb.append(", hasErrorResponseObject=").append(hasErrorResponseObject);
|
||||
sb.append(", isRestfulIndex=").append(isRestfulIndex);
|
||||
sb.append(", isRestfulShow=").append(isRestfulShow);
|
||||
sb.append(", isRestfulCreate=").append(isRestfulCreate);
|
||||
@ -371,6 +373,7 @@ public class CodegenOperation {
|
||||
isResponseFile == that.isResponseFile &&
|
||||
hasReference == that.hasReference &&
|
||||
hasDefaultResponse == that.hasDefaultResponse &&
|
||||
hasErrorResponseObject == that.hasErrorResponseObject &&
|
||||
isRestfulIndex == that.isRestfulIndex &&
|
||||
isRestfulShow == that.isRestfulShow &&
|
||||
isRestfulCreate == that.isRestfulCreate &&
|
||||
@ -435,6 +438,7 @@ public class CodegenOperation {
|
||||
produces, prioritizedContentTypes, servers, bodyParam, allParams, bodyParams, pathParams, queryParams,
|
||||
headerParams, formParams, cookieParams, requiredParams, optionalParams, authMethods, tags,
|
||||
responses, callbacks, imports, examples, requestBodyExamples, externalDocs, vendorExtensions,
|
||||
nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase, operationIdSnakeCase);
|
||||
nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase, operationIdSnakeCase,
|
||||
hasErrorResponseObject);
|
||||
}
|
||||
}
|
||||
|
@ -570,14 +570,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
|
||||
for (Map<String, Object> mo : models) {
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
for (CodegenProperty cp : cm.allVars) {
|
||||
// detect self import
|
||||
if (cp.dataType.equalsIgnoreCase(cm.classname) ||
|
||||
(cp.isContainer && cp.items != null && cp.items.dataType.equalsIgnoreCase(cm.classname))) {
|
||||
cm.imports.remove(cm.classname); // remove self import
|
||||
cp.isSelfReference = true;
|
||||
}
|
||||
}
|
||||
removeSelfReferenceImports(cm);
|
||||
}
|
||||
}
|
||||
setCircularReferences(allModels);
|
||||
@ -585,6 +578,23 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
return objs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes imports from the model that points to itself
|
||||
* Marks a self referencing property, if detected
|
||||
*
|
||||
* @param model Self imports will be removed from this model.imports collection
|
||||
*/
|
||||
protected void removeSelfReferenceImports(CodegenModel model) {
|
||||
for (CodegenProperty cp : model.allVars) {
|
||||
// detect self import
|
||||
if (cp.dataType.equalsIgnoreCase(model.classname) ||
|
||||
(cp.isContainer && cp.items != null && cp.items.dataType.equalsIgnoreCase(model.classname))) {
|
||||
model.imports.remove(model.classname); // remove self import
|
||||
cp.isSelfReference = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCircularReferences(Map<String, CodegenModel> models) {
|
||||
final Map<String, List<CodegenProperty>> dependencyMap = models.entrySet().stream()
|
||||
.collect(Collectors.toMap(Entry::getKey, entry -> getModelDependencies(entry.getValue())));
|
||||
@ -3966,6 +3976,12 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
if (Boolean.TRUE.equals(r.isFile) && Boolean.TRUE.equals(r.is2xx) && Boolean.FALSE.equals(op.isResponseFile)) {
|
||||
op.isResponseFile = Boolean.TRUE;
|
||||
}
|
||||
|
||||
// check if any 4xx or 5xx reponse has an error response object defined
|
||||
if ((Boolean.TRUE.equals(r.is4xx) || Boolean.TRUE.equals(r.is5xx)) &&
|
||||
Boolean.FALSE.equals(r.primitiveType) && Boolean.FALSE.equals(r.simpleType)) {
|
||||
op.hasErrorResponseObject = Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
op.responses.sort((a, b) -> {
|
||||
int aScore = a.isWildcard() ? 2 : a.isRange() ? 1 : 0;
|
||||
@ -4259,6 +4275,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
r.setComposedSchemas(getComposedSchemas(responseSchema));
|
||||
if (ModelUtils.isArraySchema(responseSchema)) {
|
||||
r.simpleType = false;
|
||||
r.isArray = true;
|
||||
r.containerType = cp.containerType;
|
||||
ArraySchema as = (ArraySchema) responseSchema;
|
||||
CodegenProperty items = fromProperty("response", getSchemaItems(as));
|
||||
@ -4314,6 +4331,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
} else if (ModelUtils.isTypeObjectSchema(responseSchema)) {
|
||||
if (ModelUtils.isFreeFormObject(openAPI, responseSchema)) {
|
||||
r.isFreeFormObject = true;
|
||||
} else {
|
||||
r.isModel = true;
|
||||
}
|
||||
r.simpleType = false;
|
||||
r.containerType = cp.containerType;
|
||||
@ -4325,9 +4344,6 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
LOGGER.debug("Property type is not primitive: {}", cp.dataType);
|
||||
}
|
||||
|
||||
if (!r.isMap && !r.isArray) {
|
||||
r.simpleType = true;
|
||||
}
|
||||
r.primitiveType = (r.baseType == null || languageSpecificPrimitives().contains(r.baseType));
|
||||
|
||||
if (r.baseType == null) {
|
||||
@ -4774,12 +4790,12 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
final CodegenSecurity cs = defaultCodegenSecurity(key, securityScheme);
|
||||
cs.isKeyInHeader = cs.isKeyInQuery = cs.isKeyInCookie = cs.isApiKey = cs.isOAuth = false;
|
||||
cs.isBasic = true;
|
||||
if ("basic".equals(securityScheme.getScheme())) {
|
||||
if ("basic".equalsIgnoreCase(securityScheme.getScheme())) {
|
||||
cs.isBasicBasic = true;
|
||||
} else if ("bearer".equals(securityScheme.getScheme())) {
|
||||
} else if ("bearer".equalsIgnoreCase(securityScheme.getScheme())) {
|
||||
cs.isBasicBearer = true;
|
||||
cs.bearerFormat = securityScheme.getBearerFormat();
|
||||
} else if ("signature".equals(securityScheme.getScheme())) {
|
||||
} else if ("signature".equalsIgnoreCase(securityScheme.getScheme())) {
|
||||
// HTTP signature as defined in https://datatracker.ietf.org/doc/draft-cavage-http-signatures/
|
||||
// The registry of security schemes is maintained by IANA.
|
||||
// https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml
|
||||
@ -5168,17 +5184,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
cm.hasOnlyReadOnly = false;
|
||||
}
|
||||
|
||||
// TODO revise the logic to include map
|
||||
if (cp.isContainer) {
|
||||
addImport(cm, typeMapping.get("array"));
|
||||
}
|
||||
|
||||
addImport(cm, cp.baseType);
|
||||
CodegenProperty innerCp = cp;
|
||||
while (innerCp != null) {
|
||||
addImport(cm, innerCp.complexType);
|
||||
innerCp = innerCp.items;
|
||||
}
|
||||
addImportsForPropertyType(cm, cp);
|
||||
|
||||
// if required, add to the list "requiredVars"
|
||||
if (Boolean.TRUE.equals(cp.required)) {
|
||||
@ -5199,6 +5205,28 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given property, adds all needed imports to the model
|
||||
* This includes a flat property type (e.g. property type: ReferencedModel)
|
||||
* as well as container type (property type: array of ReferencedModel's)
|
||||
*
|
||||
* @param model The codegen representation of the OAS schema.
|
||||
* @param property The codegen representation of the OAS schema's property.
|
||||
*/
|
||||
protected void addImportsForPropertyType(CodegenModel model, CodegenProperty property) {
|
||||
// TODO revise the logic to include map
|
||||
if (property.isContainer) {
|
||||
addImport(model, typeMapping.get("array"));
|
||||
}
|
||||
|
||||
addImport(model, property.baseType);
|
||||
CodegenProperty innerCp = property;
|
||||
while (innerCp != null) {
|
||||
addImport(model, innerCp.complexType);
|
||||
innerCp = innerCp.items;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine all of the types in the model definitions (schemas) that are aliases of
|
||||
* simple types.
|
||||
@ -6558,6 +6586,10 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
codegenParameter.pattern = toRegularExpression(schema.getPattern());
|
||||
}
|
||||
|
||||
protected String toMediaTypeSchemaName(String contentType) {
|
||||
return toModelName(contentType + "Schema");
|
||||
}
|
||||
|
||||
protected LinkedHashMap<String, CodegenMediaType> getContent(Content content, Set<String> imports) {
|
||||
if (content == null) {
|
||||
return null;
|
||||
@ -6605,9 +6637,9 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
ceMap.put(propName, ce);
|
||||
}
|
||||
}
|
||||
CodegenProperty schemaProp = fromProperty("schema", mt.getSchema());
|
||||
CodegenMediaType codegenMt = new CodegenMediaType(schemaProp, ceMap);
|
||||
String contentType = contentEntry.getKey();
|
||||
CodegenProperty schemaProp = fromProperty(toMediaTypeSchemaName(contentType), mt.getSchema());
|
||||
CodegenMediaType codegenMt = new CodegenMediaType(schemaProp, ceMap);
|
||||
cmtContent.put(contentType, codegenMt);
|
||||
}
|
||||
return cmtContent;
|
||||
|
@ -505,7 +505,7 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
|
||||
super.postProcessModelProperty(model, property);
|
||||
if (!model.isEnum && property.isEnum) {
|
||||
// These are inner enums, enums which do not exist as models, just as properties.
|
||||
// They are handled via the enum_inline template and and are generated in the
|
||||
// They are handled via the enum_inline template and are generated in the
|
||||
// same file as the containing class. To prevent name clashes the inline enum classes
|
||||
// are prefix with the classname of the containing class in the template.
|
||||
// Here the datatypeWithEnum template variable gets updated to match that scheme.
|
||||
@ -529,9 +529,9 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List<Server> servers) {
|
||||
final CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers);
|
||||
for (CodegenResponse r : op.responses) {
|
||||
// By default only set types are automatically added to operation imports, not sure why.
|
||||
// By default, only set types are automatically added to operation imports, not sure why.
|
||||
// Add all container type imports here, by default 'dart:core' imports are skipped
|
||||
// but other sub classes may required specific container type imports.
|
||||
// but other sub-classes may require specific container type imports.
|
||||
if (r.containerType != null && typeMapping().containsKey(r.containerType)) {
|
||||
final String value = typeMapping().get(r.containerType);
|
||||
if (needToImport(value)) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,82 @@
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import org.openapitools.codegen.*;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.swagger.models.parameters.Parameter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CsharpNetcoreFunctionsServerCodegen extends CSharpNetCoreReducedClientCodegen {
|
||||
public static final String PROJECT_NAME = "projectName";
|
||||
|
||||
final Logger LOGGER = LoggerFactory.getLogger(CsharpNetcoreFunctionsServerCodegen.class);
|
||||
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.SERVER;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "csharp-netcore-functions";
|
||||
}
|
||||
|
||||
public String getHelp() {
|
||||
return "Generates a csharp server.";
|
||||
}
|
||||
|
||||
public CsharpNetcoreFunctionsServerCodegen() {
|
||||
super();
|
||||
outputFolder = "generated-code" + File.separator + "csharp";
|
||||
modelTemplateFiles.put("model.mustache", ".cs");
|
||||
apiTemplateFiles.put("functions.mustache", ".cs");
|
||||
embeddedTemplateDir = templateDir = "csharp-netcore-functions";
|
||||
apiPackage = "Apis";
|
||||
modelPackage = "Models";
|
||||
String clientPackageDir = "generatedSrc/Client";
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "generatedSrc", "README.md"));
|
||||
supportingFiles.add(new SupportingFile("project.mustache", "generatedSrc", "project.json"));
|
||||
|
||||
supportingFiles.add(new SupportingFile("IApiAccessor.mustache",
|
||||
clientPackageDir, "IApiAccessor.cs"));
|
||||
supportingFiles.add(new SupportingFile("Configuration.mustache",
|
||||
clientPackageDir, "Configuration.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiClient.mustache",
|
||||
clientPackageDir, "ApiClient.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiException.mustache",
|
||||
clientPackageDir, "ApiException.cs"));
|
||||
supportingFiles.add(new SupportingFile("ApiResponse.mustache",
|
||||
clientPackageDir, "ApiResponse.cs"));
|
||||
supportingFiles.add(new SupportingFile("ExceptionFactory.mustache",
|
||||
clientPackageDir, "ExceptionFactory.cs"));
|
||||
supportingFiles.add(new SupportingFile("OpenAPIDateConverter.mustache",
|
||||
clientPackageDir, "OpenAPIDateConverter.cs"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + File.separator + "generatedSrc" + File.separator + "Functions";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + File.separator + "generatedSrc" + File.separator + "Models";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiDocFileFolder() {
|
||||
return (outputFolder + "/Docs").replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiTestFileFolder() {
|
||||
return outputFolder + File.separator + "Tests" + File.separator + "Tests" + File.separator + apiPackage();
|
||||
}
|
||||
|
||||
}
|
@ -323,6 +323,21 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
|
||||
// enums are generated with built_value and make use of BuiltSet
|
||||
model.imports.add("BuiltSet");
|
||||
}
|
||||
|
||||
if (property.isContainer) {
|
||||
// Figure out if there are any container type additionalProperties
|
||||
// that need a custom serializer builder factory added.
|
||||
final CodegenProperty items = property.items;
|
||||
if (items.getAdditionalProperties() != null) {
|
||||
addBuiltValueSerializer(new BuiltValueSerializer(
|
||||
items.isArray,
|
||||
items.getUniqueItems(),
|
||||
items.isMap,
|
||||
items.items.isNullable,
|
||||
items.getAdditionalProperties().dataType
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,7 +347,6 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
|
||||
|
||||
Set<Map<String, Object>> serializers = new HashSet<>();
|
||||
Set<String> resultImports = new HashSet<>();
|
||||
|
||||
for (CodegenOperation op : operationList) {
|
||||
@ -370,12 +384,13 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
|
||||
// Generate serializer factories for all container type parameters.
|
||||
// But skip binary and file parameters, JSON serializers don't make sense there.
|
||||
if (param.isContainer && !(param.isBinary || param.isFile )) {
|
||||
final Map<String, Object> serializer = new HashMap<>();
|
||||
serializer.put("isArray", param.isArray);
|
||||
serializer.put("uniqueItems", param.uniqueItems);
|
||||
serializer.put("isMap", param.isMap);
|
||||
serializer.put("baseType", param.baseType);
|
||||
serializers.add(serializer);
|
||||
addBuiltValueSerializer(new BuiltValueSerializer(
|
||||
param.isArray,
|
||||
param.uniqueItems,
|
||||
param.isMap,
|
||||
param.items.isNullable,
|
||||
param.baseType
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,17 +402,17 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
|
||||
// Generate serializer factories for response types.
|
||||
// But skip binary and file response, JSON serializers don't make sense there.
|
||||
if (op.returnContainer != null && !(op.isResponseBinary || op.isResponseFile)) {
|
||||
final Map<String, Object> serializer = new HashMap<>();
|
||||
serializer.put("isArray", Objects.equals("array", op.returnContainer) || Objects.equals("set", op.returnContainer));
|
||||
serializer.put("uniqueItems", op.uniqueItems);
|
||||
serializer.put("isMap", Objects.equals("map", op.returnContainer));
|
||||
serializer.put("baseType", op.returnBaseType);
|
||||
serializers.add(serializer);
|
||||
addBuiltValueSerializer(new BuiltValueSerializer(
|
||||
Objects.equals("array", op.returnContainer) || Objects.equals("set", op.returnContainer),
|
||||
op.uniqueItems,
|
||||
Objects.equals("map", op.returnContainer),
|
||||
false,
|
||||
op.returnBaseType
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
objs.put("imports", resultImports.stream().sorted().collect(Collectors.toList()));
|
||||
objs.put("serializers", serializers);
|
||||
|
||||
return objs;
|
||||
}
|
||||
@ -410,6 +425,19 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the serializer to the global list of custom built_value serializers.
|
||||
* @param serializer
|
||||
*/
|
||||
private void addBuiltValueSerializer(BuiltValueSerializer serializer) {
|
||||
System.out.println("######## Add serializer!");
|
||||
additionalProperties.compute("builtValueSerializers", (k, v) -> {
|
||||
Set<BuiltValueSerializer> serializers = v == null ? Sets.newHashSet() : ((Set<BuiltValueSerializer>) v);
|
||||
serializers.add(serializer);
|
||||
return serializers;
|
||||
});
|
||||
}
|
||||
|
||||
private Set<String> rewriteImports(Set<String> originalImports, boolean isModel) {
|
||||
Set<String> resultImports = Sets.newHashSet();
|
||||
for (String modelImport : originalImports) {
|
||||
@ -428,4 +456,58 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
|
||||
}
|
||||
return resultImports;
|
||||
}
|
||||
|
||||
static class BuiltValueSerializer {
|
||||
|
||||
final boolean isArray;
|
||||
|
||||
final boolean uniqueItems;
|
||||
|
||||
final boolean isMap;
|
||||
|
||||
final boolean isNullable;
|
||||
|
||||
final String dataType;
|
||||
|
||||
private BuiltValueSerializer(boolean isArray, boolean uniqueItems, boolean isMap, boolean isNullable, String dataType) {
|
||||
this.isArray = isArray;
|
||||
this.uniqueItems = uniqueItems;
|
||||
this.isMap = isMap;
|
||||
this.isNullable = isNullable;
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return isArray;
|
||||
}
|
||||
|
||||
public boolean isUniqueItems() {
|
||||
return uniqueItems;
|
||||
}
|
||||
|
||||
public boolean isMap() {
|
||||
return isMap;
|
||||
}
|
||||
|
||||
public boolean isNullable() {
|
||||
return isNullable;
|
||||
}
|
||||
|
||||
public String getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
BuiltValueSerializer that = (BuiltValueSerializer) o;
|
||||
return isArray == that.isArray && uniqueItems == that.uniqueItems && isMap == that.isMap && isNullable == that.isNullable && dataType.equals(that.dataType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(isArray, uniqueItems, isMap, isNullable, dataType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -613,7 +613,7 @@ public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
return "%{}";
|
||||
}
|
||||
// Primitive return type, don't even try to decode
|
||||
if (baseType == null || (simpleType && primitiveType)) {
|
||||
if (baseType == null || (containerType == null && primitiveType)) {
|
||||
return "false";
|
||||
} else if (isArray && languageSpecificPrimitives().contains(baseType)) {
|
||||
return "[]";
|
||||
@ -733,16 +733,13 @@ public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
StringBuilder returnEntry = new StringBuilder();
|
||||
if (exResponse.baseType == null) {
|
||||
returnEntry.append("nil");
|
||||
} else if (exResponse.simpleType) {
|
||||
} else if (exResponse.containerType == null) { // not container (array, map, set)
|
||||
if (!exResponse.primitiveType) {
|
||||
returnEntry.append(moduleName);
|
||||
returnEntry.append(".Model.");
|
||||
}
|
||||
returnEntry.append(exResponse.baseType);
|
||||
returnEntry.append(".t");
|
||||
} else if (exResponse.containerType == null) {
|
||||
returnEntry.append(returnBaseType);
|
||||
returnEntry.append(".t");
|
||||
} else {
|
||||
if (exResponse.containerType.equals("array") ||
|
||||
exResponse.containerType.equals("set")) {
|
||||
|
@ -215,6 +215,9 @@ public class PythonLegacyClientCodegen extends AbstractPythonCodegen implements
|
||||
}
|
||||
}
|
||||
|
||||
String modelPath = packagePath() + File.separatorChar + modelPackage.replace('.', File.separatorChar);
|
||||
String apiPath = packagePath() + File.separatorChar + apiPackage.replace('.', File.separatorChar);
|
||||
|
||||
String readmePath = "README.md";
|
||||
String readmeTemplate = "README.mustache";
|
||||
if (generateSourceCodeOnly) {
|
||||
@ -237,8 +240,8 @@ public class PythonLegacyClientCodegen extends AbstractPythonCodegen implements
|
||||
}
|
||||
supportingFiles.add(new SupportingFile("configuration.mustache", packagePath(), "configuration.py"));
|
||||
supportingFiles.add(new SupportingFile("__init__package.mustache", packagePath(), "__init__.py"));
|
||||
supportingFiles.add(new SupportingFile("__init__model.mustache", packagePath() + File.separatorChar + modelPackage, "__init__.py"));
|
||||
supportingFiles.add(new SupportingFile("__init__api.mustache", packagePath() + File.separatorChar + apiPackage, "__init__.py"));
|
||||
supportingFiles.add(new SupportingFile("__init__model.mustache", modelPath, "__init__.py"));
|
||||
supportingFiles.add(new SupportingFile("__init__api.mustache", apiPath, "__init__.py"));
|
||||
|
||||
// If the package name consists of dots(openapi.client), then we need to create the directory structure like openapi/client with __init__ files.
|
||||
String[] packageNameSplits = packageName.split("\\.");
|
||||
|
@ -66,6 +66,7 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
public static final String SWIFT_PACKAGE_PATH = "swiftPackagePath";
|
||||
public static final String USE_CLASSES = "useClasses";
|
||||
public static final String USE_BACKTICK_ESCAPES = "useBacktickEscapes";
|
||||
public static final String GENERATE_FROZEN_ENUMS = "generateFrozenEnums";
|
||||
public static final String GENERATE_MODEL_ADDITIONAL_PROPERTIES = "generateModelAdditionalProperties";
|
||||
public static final String HASHABLE_MODELS = "hashableModels";
|
||||
public static final String MAP_FILE_BINARY_TO_DATA = "mapFileBinaryToData";
|
||||
@ -90,6 +91,7 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
protected boolean useClasses = false;
|
||||
protected boolean useBacktickEscapes = false;
|
||||
protected boolean generateModelAdditionalProperties = true;
|
||||
protected boolean generateFrozenEnums = true;
|
||||
protected boolean hashableModels = true;
|
||||
protected boolean mapFileBinaryToData = false;
|
||||
protected String[] responseAs = new String[0];
|
||||
@ -281,6 +283,9 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
cliOptions.add(new CliOption(USE_BACKTICK_ESCAPES,
|
||||
"Escape reserved words using backticks (default: false)")
|
||||
.defaultValue(Boolean.FALSE.toString()));
|
||||
cliOptions.add(new CliOption(GENERATE_FROZEN_ENUMS,
|
||||
"Generate frozen enums (default: true)")
|
||||
.defaultValue(Boolean.TRUE.toString()));
|
||||
cliOptions.add(new CliOption(GENERATE_MODEL_ADDITIONAL_PROPERTIES,
|
||||
"Generate model additional properties (default: true)")
|
||||
.defaultValue(Boolean.TRUE.toString()));
|
||||
@ -485,6 +490,13 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
setUseBacktickEscapes(convertPropertyToBooleanAndWriteBack(USE_BACKTICK_ESCAPES));
|
||||
}
|
||||
|
||||
// Setup generateFrozenEnums option. If true, enums will strictly include
|
||||
// cases matching the spec. If false, enums will also include an extra catch-all case.
|
||||
if (additionalProperties.containsKey(GENERATE_FROZEN_ENUMS)) {
|
||||
setGenerateFrozenEnums(convertPropertyToBooleanAndWriteBack(GENERATE_FROZEN_ENUMS));
|
||||
}
|
||||
additionalProperties.put(GENERATE_FROZEN_ENUMS, generateFrozenEnums);
|
||||
|
||||
if (additionalProperties.containsKey(GENERATE_MODEL_ADDITIONAL_PROPERTIES)) {
|
||||
setGenerateModelAdditionalProperties(convertPropertyToBooleanAndWriteBack(GENERATE_MODEL_ADDITIONAL_PROPERTIES));
|
||||
}
|
||||
@ -943,6 +955,10 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
this.useBacktickEscapes = useBacktickEscapes;
|
||||
}
|
||||
|
||||
public void setGenerateFrozenEnums(boolean generateFrozenEnums) {
|
||||
this.generateFrozenEnums = generateFrozenEnums;
|
||||
}
|
||||
|
||||
public void setGenerateModelAdditionalProperties(boolean generateModelAdditionalProperties) {
|
||||
this.generateModelAdditionalProperties = generateModelAdditionalProperties;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
|
||||
public static final String STRING_ENUMS_DESC = "Generate string enums instead of objects for enum values.";
|
||||
public static final String QUERY_PARAM_OBJECT_FORMAT = "queryParamObjectFormat";
|
||||
|
||||
protected String ngVersion = "12.2.12";
|
||||
protected String ngVersion = "13.0.1";
|
||||
protected String npmRepository = null;
|
||||
private boolean useSingleRequestParameter = false;
|
||||
protected String serviceSuffix = "Service";
|
||||
@ -146,7 +146,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
|
||||
|
||||
@Override
|
||||
public String getHelp() {
|
||||
return "Generates a TypeScript Angular (6.x - 12.x) client library.";
|
||||
return "Generates a TypeScript Angular (6.x - 13.x) client library.";
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -243,7 +243,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
|
||||
} else {
|
||||
additionalProperties.put(DELETE_ACCEPTS_BODY, false);
|
||||
}
|
||||
|
||||
|
||||
additionalProperties.put(NG_VERSION, ngVersion);
|
||||
|
||||
if (additionalProperties.containsKey(API_MODULE_PREFIX)) {
|
||||
@ -300,7 +300,9 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
|
||||
}
|
||||
|
||||
// Set the typescript version compatible to the Angular version
|
||||
if (ngVersion.atLeast("12.0.0")) {
|
||||
if (ngVersion.atLeast("13.0.0")) {
|
||||
additionalProperties.put("tsVersion", ">=4.4.2 <4.5.0");
|
||||
} else if (ngVersion.atLeast("12.0.0")) {
|
||||
additionalProperties.put("tsVersion", ">=4.3.0 <4.4.0");
|
||||
} else if (ngVersion.atLeast("11.0.0")) {
|
||||
additionalProperties.put("tsVersion", ">=4.0.0 <4.1.0");
|
||||
@ -318,7 +320,9 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
|
||||
}
|
||||
|
||||
// Set the rxJS version compatible to the Angular version
|
||||
if (ngVersion.atLeast("10.0.0")) {
|
||||
if (ngVersion.atLeast("13.0.0")) {
|
||||
additionalProperties.put("rxjsVersion", "7.4.0");
|
||||
} else if (ngVersion.atLeast("10.0.0")) {
|
||||
additionalProperties.put("rxjsVersion", "6.6.0");
|
||||
} else if (ngVersion.atLeast("9.0.0")) {
|
||||
additionalProperties.put("rxjsVersion", "6.5.3");
|
||||
@ -334,7 +338,10 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
|
||||
supportingFiles.add(new SupportingFile("ng-package.mustache", getIndexDirectory(), "ng-package.json"));
|
||||
|
||||
// Specific ng-packagr configuration
|
||||
if (ngVersion.atLeast("12.0.0")) {
|
||||
if (ngVersion.atLeast("13.0.0")) {
|
||||
additionalProperties.put("ngPackagrVersion", "13.0.3");
|
||||
additionalProperties.put("tsickleVersion", "0.43.0");
|
||||
} else if (ngVersion.atLeast("12.0.0")) {
|
||||
additionalProperties.put("ngPackagrVersion", "12.2.1");
|
||||
additionalProperties.put("tsickleVersion", "0.43.0");
|
||||
} else if (ngVersion.atLeast("11.0.0")) {
|
||||
@ -542,8 +549,19 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
|
||||
setChildDiscriminatorValue(cm, child);
|
||||
}
|
||||
}
|
||||
|
||||
// with tagged union, a child model doesn't extend the parent (all properties are just copied over)
|
||||
// it means we don't need to import that parent any more
|
||||
if (cm.parent != null) {
|
||||
cm.imports.remove(cm.parent);
|
||||
|
||||
// however, it's possible that the child model contains a recursive reference to the parent
|
||||
// in order to support this case, we update the list of imports from properties once again
|
||||
for (CodegenProperty cp: cm.allVars) {
|
||||
addImportsForPropertyType(cm, cp);
|
||||
}
|
||||
removeSelfReferenceImports(cm);
|
||||
|
||||
}
|
||||
}
|
||||
// Add additional filename information for imports
|
||||
|
@ -132,21 +132,9 @@ public class JSON {
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{^isEnum}}
|
||||
{{#oneOf}}
|
||||
{{#-first}}
|
||||
{{^hasChildren}}
|
||||
.registerTypeAdapterFactory(new {{modelPackage}}.{{{classname}}}.CustomTypeAdapterFactory())
|
||||
{{/-first}}
|
||||
{{/oneOf}}
|
||||
{{^oneOf}}
|
||||
{{#anyOf}}
|
||||
{{#-first}}
|
||||
.registerTypeAdapterFactory(new {{modelPackage}}.{{{classname}}}.CustomTypeAdapterFactory())
|
||||
{{/-first}}
|
||||
{{/anyOf}}
|
||||
{{^anyOf}}
|
||||
.registerTypeAdapterFactory(new {{modelPackage}}.{{{classname}}}.CustomTypeAdapterFactory())
|
||||
{{/anyOf}}
|
||||
{{/oneOf}}
|
||||
{{/hasChildren}}
|
||||
{{/isEnum}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
|
@ -379,6 +379,7 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
|
||||
}
|
||||
};
|
||||
{{/parcelableModel}}
|
||||
{{^hasChildren}}
|
||||
public static HashSet<String> openapiFields;
|
||||
public static HashSet<String> openapiRequiredFields;
|
||||
|
||||
@ -442,4 +443,5 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
|
||||
}.nullSafe();
|
||||
}
|
||||
}
|
||||
{{/hasChildren}}
|
||||
}
|
@ -23,6 +23,7 @@ org.openapitools.codegen.languages.CSharpClientCodegen
|
||||
org.openapitools.codegen.languages.CSharpNetCoreClientCodegen
|
||||
org.openapitools.codegen.languages.CSharpDotNet2ClientCodegen
|
||||
org.openapitools.codegen.languages.CSharpNancyFXServerCodegen
|
||||
org.openapitools.codegen.languages.CsharpNetcoreFunctionsServerCodegen
|
||||
org.openapitools.codegen.languages.DartClientCodegen
|
||||
org.openapitools.codegen.languages.DartDioClientCodegen
|
||||
org.openapitools.codegen.languages.DartDioNextClientCodegen
|
||||
|
@ -104,7 +104,7 @@ Operation Id:: {{nickname}}
|
||||
|
||||
| {{code}}
|
||||
| {{message}}
|
||||
| {{^simpleType}}{{dataType}}[<<{{baseType}}>>]{{/simpleType}} {{#simpleType}}<<{{dataType}}>>{{/simpleType}}
|
||||
| {{#containerType}}{{dataType}}[<<{{baseType}}>>]{{/containerType}} {{^containerType}}<<{{dataType}}>>{{/containerType}}
|
||||
|
||||
{{/responses}}
|
||||
|===
|
||||
|
@ -0,0 +1,68 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace {{packageName}}.{{modelPackage}}
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract base class for oneOf, anyOf schemas in the OpenAPI specification
|
||||
/// </summary>
|
||||
{{>visibility}} abstract partial class AbstractOpenAPISchema
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom JSON serializer
|
||||
/// </summary>
|
||||
static public readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
// OpenAPI generated types generally hide default constructors.
|
||||
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
|
||||
MissingMemberHandling = MissingMemberHandling.Error,
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy
|
||||
{
|
||||
OverrideSpecifiedNames = false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Custom JSON serializer for objects with additional properties
|
||||
/// </summary>
|
||||
static public readonly JsonSerializerSettings AdditionalPropertiesSerializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
// OpenAPI generated types generally hide default constructors.
|
||||
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
|
||||
MissingMemberHandling = MissingMemberHandling.Ignore,
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy
|
||||
{
|
||||
OverrideSpecifiedNames = false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets the actual instance
|
||||
/// </summary>
|
||||
public abstract Object ActualInstance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets IsNullable to indicate whether the instance is nullable
|
||||
/// </summary>
|
||||
public bool IsNullable { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets the schema type, which can be either `oneOf` or `anyOf`
|
||||
/// </summary>
|
||||
public string SchemaType { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts the instance into JSON string.
|
||||
/// </summary>
|
||||
public abstract string ToJson();
|
||||
}
|
||||
}
|
867
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ApiClient.mustache
vendored
Normal file
867
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ApiClient.mustache
vendored
Normal file
@ -0,0 +1,867 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
{{^netStandard}}
|
||||
using System.Web;
|
||||
{{/netStandard}}
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
||||
using RestSharp;
|
||||
using RestSharp.Deserializers;
|
||||
using RestSharpMethod = RestSharp.Method;
|
||||
{{#useWebRequest}}
|
||||
using System.Net.Http;
|
||||
{{/useWebRequest}}
|
||||
{{#supportsRetry}}
|
||||
using Polly;
|
||||
{{/supportsRetry}}
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows RestSharp to Serialize/Deserialize JSON using our custom logic, but only when ContentType is JSON.
|
||||
/// </summary>
|
||||
internal class CustomJsonCodec : RestSharp.Serializers.ISerializer, RestSharp.Deserializers.IDeserializer
|
||||
{
|
||||
private readonly IReadableConfiguration _configuration;
|
||||
private static readonly string _contentType = "application/json";
|
||||
private readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
// OpenAPI generated types generally hide default constructors.
|
||||
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy
|
||||
{
|
||||
OverrideSpecifiedNames = false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public CustomJsonCodec(IReadableConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfiguration configuration)
|
||||
{
|
||||
_serializerSettings = serializerSettings;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize the object into a JSON string.
|
||||
/// </summary>
|
||||
/// <param name="obj">Object to be serialized.</param>
|
||||
/// <returns>A JSON string.</returns>
|
||||
public string Serialize(object obj)
|
||||
{
|
||||
if (obj != null && obj is {{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema)
|
||||
{
|
||||
// the object to be serialized is an oneOf/anyOf schema
|
||||
return (({{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema)obj).ToJson();
|
||||
}
|
||||
else
|
||||
{
|
||||
return JsonConvert.SerializeObject(obj, _serializerSettings);
|
||||
}
|
||||
}
|
||||
|
||||
public T Deserialize<T>(IRestResponse response)
|
||||
{
|
||||
var result = (T)Deserialize(response, typeof(T));
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize the JSON string into a proper object.
|
||||
/// </summary>
|
||||
/// <param name="response">The HTTP response.</param>
|
||||
/// <param name="type">Object type.</param>
|
||||
/// <returns>Object representation of the JSON string.</returns>
|
||||
internal object Deserialize(IRestResponse response, Type type)
|
||||
{
|
||||
if (type == typeof(byte[])) // return byte array
|
||||
{
|
||||
return response.RawBytes;
|
||||
}
|
||||
|
||||
// TODO: ? if (type.IsAssignableFrom(typeof(Stream)))
|
||||
if (type == typeof(Stream))
|
||||
{
|
||||
var bytes = response.RawBytes;
|
||||
if (response.Headers != null)
|
||||
{
|
||||
var filePath = string.IsNullOrEmpty(_configuration.TempFolderPath)
|
||||
? Path.GetTempPath()
|
||||
: _configuration.TempFolderPath;
|
||||
var regex = new Regex(@"Content-Disposition=.*filename=['""]?([^'""\s]+)['""]?$");
|
||||
foreach (var header in response.Headers)
|
||||
{
|
||||
var match = regex.Match(header.ToString());
|
||||
if (match.Success)
|
||||
{
|
||||
string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", ""));
|
||||
File.WriteAllBytes(fileName, bytes);
|
||||
return new FileStream(fileName, FileMode.Open);
|
||||
}
|
||||
}
|
||||
}
|
||||
var stream = new MemoryStream(bytes);
|
||||
return stream;
|
||||
}
|
||||
|
||||
if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object
|
||||
{
|
||||
return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind);
|
||||
}
|
||||
|
||||
if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type
|
||||
{
|
||||
return Convert.ChangeType(response.Content, type);
|
||||
}
|
||||
|
||||
// at this point, it must be a model (json)
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(response.Content, type, _serializerSettings);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApiException(500, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public string RootElement { get; set; }
|
||||
public string Namespace { get; set; }
|
||||
public string DateFormat { get; set; }
|
||||
|
||||
public string ContentType
|
||||
{
|
||||
get { return _contentType; }
|
||||
set { throw new InvalidOperationException("Not allowed to set content type."); }
|
||||
}
|
||||
}
|
||||
{{! NOTE: Any changes related to RestSharp should be done in this class. All other client classes are for extensibility by consumers.}}
|
||||
/// <summary>
|
||||
/// Provides a default implementation of an Api client (both synchronous and asynchronous implementatios),
|
||||
/// encapsulating general REST accessor use cases.
|
||||
/// </summary>
|
||||
{{>visibility}} partial class ApiClient : ISynchronousClient{{#supportsAsync}}, IAsynchronousClient{{/supportsAsync}}
|
||||
{
|
||||
private readonly string _baseUrl;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the settings on a <see cref="JsonSerializer" /> object.
|
||||
/// These settings can be adjusted to accomodate custom serialization rules.
|
||||
/// </summary>
|
||||
public JsonSerializerSettings SerializerSettings { get; set; } = new JsonSerializerSettings
|
||||
{
|
||||
// OpenAPI generated types generally hide default constructors.
|
||||
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy
|
||||
{
|
||||
OverrideSpecifiedNames = false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Allows for extending request processing for <see cref="ApiClient"/> generated code.
|
||||
/// </summary>
|
||||
/// <param name="request">The RestSharp request object</param>
|
||||
partial void InterceptRequest(IRestRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// Allows for extending response processing for <see cref="ApiClient"/> generated code.
|
||||
/// </summary>
|
||||
/// <param name="request">The RestSharp request object</param>
|
||||
/// <param name="response">The RestSharp response object</param>
|
||||
partial void InterceptResponse(IRestRequest request, IRestResponse response);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiClient" />, defaulting to the global configurations' base url.
|
||||
/// </summary>
|
||||
public ApiClient()
|
||||
{
|
||||
_baseUrl = {{packageName}}.Client.GlobalConfiguration.Instance.BasePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiClient" />
|
||||
/// </summary>
|
||||
/// <param name="basePath">The target service's base path in URL format.</param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public ApiClient(string basePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(basePath))
|
||||
throw new ArgumentException("basePath cannot be empty");
|
||||
|
||||
_baseUrl = basePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the RestSharp version of an http method
|
||||
/// </summary>
|
||||
/// <param name="method">Swagger Client Custom HttpMethod</param>
|
||||
/// <returns>RestSharp's HttpMethod instance.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
private RestSharpMethod Method(HttpMethod method)
|
||||
{
|
||||
RestSharpMethod other;
|
||||
switch (method)
|
||||
{
|
||||
case HttpMethod.Get:
|
||||
other = RestSharpMethod.GET;
|
||||
break;
|
||||
case HttpMethod.Post:
|
||||
other = RestSharpMethod.POST;
|
||||
break;
|
||||
case HttpMethod.Put:
|
||||
other = RestSharpMethod.PUT;
|
||||
break;
|
||||
case HttpMethod.Delete:
|
||||
other = RestSharpMethod.DELETE;
|
||||
break;
|
||||
case HttpMethod.Head:
|
||||
other = RestSharpMethod.HEAD;
|
||||
break;
|
||||
case HttpMethod.Options:
|
||||
other = RestSharpMethod.OPTIONS;
|
||||
break;
|
||||
case HttpMethod.Patch:
|
||||
other = RestSharpMethod.PATCH;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("method", method, null);
|
||||
}
|
||||
|
||||
return other;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides all logic for constructing a new RestSharp <see cref="RestRequest"/>.
|
||||
/// At this point, all information for querying the service is known. Here, it is simply
|
||||
/// mapped into the RestSharp request.
|
||||
/// </summary>
|
||||
/// <param name="method">The http verb.</param>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>[private] A new RestRequest instance.</returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
private RestRequest NewRequest(
|
||||
HttpMethod method,
|
||||
string path,
|
||||
RequestOptions options,
|
||||
IReadableConfiguration configuration)
|
||||
{
|
||||
if (path == null) throw new ArgumentNullException("path");
|
||||
if (options == null) throw new ArgumentNullException("options");
|
||||
if (configuration == null) throw new ArgumentNullException("configuration");
|
||||
|
||||
RestRequest request = new RestRequest(Method(method))
|
||||
{
|
||||
Resource = path,
|
||||
JsonSerializer = new CustomJsonCodec(SerializerSettings, configuration)
|
||||
};
|
||||
|
||||
if (options.PathParameters != null)
|
||||
{
|
||||
foreach (var pathParam in options.PathParameters)
|
||||
{
|
||||
request.AddParameter(pathParam.Key, pathParam.Value, ParameterType.UrlSegment);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.QueryParameters != null)
|
||||
{
|
||||
foreach (var queryParam in options.QueryParameters)
|
||||
{
|
||||
foreach (var value in queryParam.Value)
|
||||
{
|
||||
request.AddQueryParameter(queryParam.Key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (configuration.DefaultHeaders != null)
|
||||
{
|
||||
foreach (var headerParam in configuration.DefaultHeaders)
|
||||
{
|
||||
request.AddHeader(headerParam.Key, headerParam.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.HeaderParameters != null)
|
||||
{
|
||||
foreach (var headerParam in options.HeaderParameters)
|
||||
{
|
||||
foreach (var value in headerParam.Value)
|
||||
{
|
||||
request.AddHeader(headerParam.Key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.FormParameters != null)
|
||||
{
|
||||
foreach (var formParam in options.FormParameters)
|
||||
{
|
||||
request.AddParameter(formParam.Key, formParam.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.Data != null)
|
||||
{
|
||||
if (options.Data is Stream stream)
|
||||
{
|
||||
var contentType = "application/octet-stream";
|
||||
if (options.HeaderParameters != null)
|
||||
{
|
||||
var contentTypes = options.HeaderParameters["Content-Type"];
|
||||
contentType = contentTypes[0];
|
||||
}
|
||||
|
||||
var bytes = ClientUtils.ReadAsBytes(stream);
|
||||
request.AddParameter(contentType, bytes, ParameterType.RequestBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (options.HeaderParameters != null)
|
||||
{
|
||||
var contentTypes = options.HeaderParameters["Content-Type"];
|
||||
if (contentTypes == null || contentTypes.Any(header => header.Contains("application/json")))
|
||||
{
|
||||
request.RequestFormat = DataFormat.Json;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Generated client user should add additional handlers. RestSharp only supports XML and JSON, with XML as default.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Here, we'll assume JSON APIs are more common. XML can be forced by adding produces/consumes to openapi spec explicitly.
|
||||
request.RequestFormat = DataFormat.Json;
|
||||
}
|
||||
|
||||
request.AddJsonBody(options.Data);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.FileParameters != null)
|
||||
{
|
||||
foreach (var fileParam in options.FileParameters)
|
||||
{
|
||||
var bytes = ClientUtils.ReadAsBytes(fileParam.Value);
|
||||
var fileStream = fileParam.Value as FileStream;
|
||||
if (fileStream != null)
|
||||
request.Files.Add(FileParameter.Create(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)));
|
||||
else
|
||||
request.Files.Add(FileParameter.Create(fileParam.Key, bytes, "no_file_name_provided"));
|
||||
}
|
||||
}
|
||||
|
||||
if (options.Cookies != null && options.Cookies.Count > 0)
|
||||
{
|
||||
foreach (var cookie in options.Cookies)
|
||||
{
|
||||
request.AddCookie(cookie.Name, cookie.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
private ApiResponse<T> ToApiResponse<T>(IRestResponse<T> response)
|
||||
{
|
||||
T result = response.Data;
|
||||
string rawContent = response.Content;
|
||||
|
||||
var transformed = new ApiResponse<T>(response.StatusCode, new Multimap<string, string>({{#caseInsensitiveResponseHeaders}}StringComparer.OrdinalIgnoreCase{{/caseInsensitiveResponseHeaders}}), result, rawContent)
|
||||
{
|
||||
ErrorText = response.ErrorMessage,
|
||||
Cookies = new List<Cookie>()
|
||||
};
|
||||
|
||||
if (response.Headers != null)
|
||||
{
|
||||
foreach (var responseHeader in response.Headers)
|
||||
{
|
||||
transformed.Headers.Add(responseHeader.Name, ClientUtils.ParameterToString(responseHeader.Value));
|
||||
}
|
||||
}
|
||||
|
||||
if (response.Cookies != null)
|
||||
{
|
||||
foreach (var responseCookies in response.Cookies)
|
||||
{
|
||||
transformed.Cookies.Add(
|
||||
new Cookie(
|
||||
responseCookies.Name,
|
||||
responseCookies.Value,
|
||||
responseCookies.Path,
|
||||
responseCookies.Domain)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return transformed;
|
||||
}
|
||||
|
||||
private ApiResponse<T> Exec<T>(RestRequest req, IReadableConfiguration configuration)
|
||||
{
|
||||
RestClient client = new RestClient(_baseUrl);
|
||||
|
||||
client.ClearHandlers();
|
||||
var existingDeserializer = req.JsonSerializer as IDeserializer;
|
||||
if (existingDeserializer != null)
|
||||
{
|
||||
client.AddHandler("application/json", () => existingDeserializer);
|
||||
client.AddHandler("text/json", () => existingDeserializer);
|
||||
client.AddHandler("text/x-json", () => existingDeserializer);
|
||||
client.AddHandler("text/javascript", () => existingDeserializer);
|
||||
client.AddHandler("*+json", () => existingDeserializer);
|
||||
}
|
||||
else
|
||||
{
|
||||
var customDeserializer = new CustomJsonCodec(SerializerSettings, configuration);
|
||||
client.AddHandler("application/json", () => customDeserializer);
|
||||
client.AddHandler("text/json", () => customDeserializer);
|
||||
client.AddHandler("text/x-json", () => customDeserializer);
|
||||
client.AddHandler("text/javascript", () => customDeserializer);
|
||||
client.AddHandler("*+json", () => customDeserializer);
|
||||
}
|
||||
|
||||
var xmlDeserializer = new XmlDeserializer();
|
||||
client.AddHandler("application/xml", () => xmlDeserializer);
|
||||
client.AddHandler("text/xml", () => xmlDeserializer);
|
||||
client.AddHandler("*+xml", () => xmlDeserializer);
|
||||
client.AddHandler("*", () => xmlDeserializer);
|
||||
|
||||
client.Timeout = configuration.Timeout;
|
||||
|
||||
if (configuration.Proxy != null)
|
||||
{
|
||||
client.Proxy = configuration.Proxy;
|
||||
}
|
||||
|
||||
if (configuration.UserAgent != null)
|
||||
{
|
||||
client.UserAgent = configuration.UserAgent;
|
||||
}
|
||||
|
||||
if (configuration.ClientCertificates != null)
|
||||
{
|
||||
client.ClientCertificates = configuration.ClientCertificates;
|
||||
}
|
||||
|
||||
InterceptRequest(req);
|
||||
|
||||
IRestResponse<T> response;
|
||||
if (RetryConfiguration.RetryPolicy != null)
|
||||
{
|
||||
var policy = RetryConfiguration.RetryPolicy;
|
||||
var policyResult = policy.ExecuteAndCapture(() => client.Execute(req));
|
||||
response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize<T>(policyResult.Result) : new RestResponse<T>
|
||||
{
|
||||
Request = req,
|
||||
ErrorException = policyResult.FinalException
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
response = client.Execute<T>(req);
|
||||
}
|
||||
|
||||
// if the response type is oneOf/anyOf, call FromJSON to deserialize the data
|
||||
if (typeof({{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
|
||||
}
|
||||
else if (typeof(T).Name == "Stream") // for binary response
|
||||
{
|
||||
response.Data = (T)(object)new MemoryStream(response.RawBytes);
|
||||
}
|
||||
|
||||
InterceptResponse(req, response);
|
||||
|
||||
var result = ToApiResponse(response);
|
||||
if (response.ErrorMessage != null)
|
||||
{
|
||||
result.ErrorText = response.ErrorMessage;
|
||||
}
|
||||
|
||||
if (response.Cookies != null && response.Cookies.Count > 0)
|
||||
{
|
||||
if (result.Cookies == null) result.Cookies = new List<Cookie>();
|
||||
foreach (var restResponseCookie in response.Cookies)
|
||||
{
|
||||
var cookie = new Cookie(
|
||||
restResponseCookie.Name,
|
||||
restResponseCookie.Value,
|
||||
restResponseCookie.Path,
|
||||
restResponseCookie.Domain
|
||||
)
|
||||
{
|
||||
Comment = restResponseCookie.Comment,
|
||||
CommentUri = restResponseCookie.CommentUri,
|
||||
Discard = restResponseCookie.Discard,
|
||||
Expired = restResponseCookie.Expired,
|
||||
Expires = restResponseCookie.Expires,
|
||||
HttpOnly = restResponseCookie.HttpOnly,
|
||||
Port = restResponseCookie.Port,
|
||||
Secure = restResponseCookie.Secure,
|
||||
Version = restResponseCookie.Version
|
||||
};
|
||||
|
||||
result.Cookies.Add(cookie);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
{{#supportsAsync}}
|
||||
private async Task<ApiResponse<T>> ExecAsync<T>(RestRequest req, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
RestClient client = new RestClient(_baseUrl);
|
||||
|
||||
client.ClearHandlers();
|
||||
var existingDeserializer = req.JsonSerializer as IDeserializer;
|
||||
if (existingDeserializer != null)
|
||||
{
|
||||
client.AddHandler("application/json", () => existingDeserializer);
|
||||
client.AddHandler("text/json", () => existingDeserializer);
|
||||
client.AddHandler("text/x-json", () => existingDeserializer);
|
||||
client.AddHandler("text/javascript", () => existingDeserializer);
|
||||
client.AddHandler("*+json", () => existingDeserializer);
|
||||
}
|
||||
else
|
||||
{
|
||||
var customDeserializer = new CustomJsonCodec(SerializerSettings, configuration);
|
||||
client.AddHandler("application/json", () => customDeserializer);
|
||||
client.AddHandler("text/json", () => customDeserializer);
|
||||
client.AddHandler("text/x-json", () => customDeserializer);
|
||||
client.AddHandler("text/javascript", () => customDeserializer);
|
||||
client.AddHandler("*+json", () => customDeserializer);
|
||||
}
|
||||
|
||||
var xmlDeserializer = new XmlDeserializer();
|
||||
client.AddHandler("application/xml", () => xmlDeserializer);
|
||||
client.AddHandler("text/xml", () => xmlDeserializer);
|
||||
client.AddHandler("*+xml", () => xmlDeserializer);
|
||||
client.AddHandler("*", () => xmlDeserializer);
|
||||
|
||||
client.Timeout = configuration.Timeout;
|
||||
|
||||
if (configuration.Proxy != null)
|
||||
{
|
||||
client.Proxy = configuration.Proxy;
|
||||
}
|
||||
|
||||
if (configuration.UserAgent != null)
|
||||
{
|
||||
client.UserAgent = configuration.UserAgent;
|
||||
}
|
||||
|
||||
if (configuration.ClientCertificates != null)
|
||||
{
|
||||
client.ClientCertificates = configuration.ClientCertificates;
|
||||
}
|
||||
|
||||
InterceptRequest(req);
|
||||
|
||||
IRestResponse<T> response;
|
||||
{{#supportsRetry}}
|
||||
if (RetryConfiguration.AsyncRetryPolicy != null)
|
||||
{
|
||||
var policy = RetryConfiguration.AsyncRetryPolicy;
|
||||
var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(req, ct), cancellationToken).ConfigureAwait(false);
|
||||
response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize<T>(policyResult.Result) : new RestResponse<T>
|
||||
{
|
||||
Request = req,
|
||||
ErrorException = policyResult.FinalException
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
{{/supportsRetry}}
|
||||
response = await client.ExecuteAsync<T>(req, cancellationToken).ConfigureAwait(false);
|
||||
{{#supportsRetry}}
|
||||
}
|
||||
{{/supportsRetry}}
|
||||
|
||||
// if the response type is oneOf/anyOf, call FromJSON to deserialize the data
|
||||
if (typeof({{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
|
||||
}
|
||||
else if (typeof(T).Name == "Stream") // for binary response
|
||||
{
|
||||
response.Data = (T)(object)new MemoryStream(response.RawBytes);
|
||||
}
|
||||
|
||||
InterceptResponse(req, response);
|
||||
|
||||
var result = ToApiResponse(response);
|
||||
if (response.ErrorMessage != null)
|
||||
{
|
||||
result.ErrorText = response.ErrorMessage;
|
||||
}
|
||||
|
||||
if (response.Cookies != null && response.Cookies.Count > 0)
|
||||
{
|
||||
if (result.Cookies == null) result.Cookies = new List<Cookie>();
|
||||
foreach (var restResponseCookie in response.Cookies)
|
||||
{
|
||||
var cookie = new Cookie(
|
||||
restResponseCookie.Name,
|
||||
restResponseCookie.Value,
|
||||
restResponseCookie.Path,
|
||||
restResponseCookie.Domain
|
||||
)
|
||||
{
|
||||
Comment = restResponseCookie.Comment,
|
||||
CommentUri = restResponseCookie.CommentUri,
|
||||
Discard = restResponseCookie.Discard,
|
||||
Expired = restResponseCookie.Expired,
|
||||
Expires = restResponseCookie.Expires,
|
||||
HttpOnly = restResponseCookie.HttpOnly,
|
||||
Port = restResponseCookie.Port,
|
||||
Secure = restResponseCookie.Secure,
|
||||
Version = restResponseCookie.Version
|
||||
};
|
||||
|
||||
result.Cookies.Add(cookie);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#region IAsynchronousClient
|
||||
/// <summary>
|
||||
/// Make a HTTP GET request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> GetAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Get, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP POST request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> PostAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Post, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP PUT request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> PutAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Put, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP DELETE request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> DeleteAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Delete, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP HEAD request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> HeadAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Head, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP OPTION request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> OptionsAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Options, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP PATCH request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> PatchAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Patch, path, options, config), config, cancellationToken);
|
||||
}
|
||||
#endregion IAsynchronousClient
|
||||
{{/supportsAsync}}
|
||||
|
||||
#region ISynchronousClient
|
||||
/// <summary>
|
||||
/// Make a HTTP GET request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Get<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Get, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP POST request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Post<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Post, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP PUT request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Put<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Put, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP DELETE request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Delete<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Delete, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP HEAD request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Head<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Head, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP OPTION request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Options<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Options, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP PATCH request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Patch<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Patch, path, options, config), config);
|
||||
}
|
||||
#endregion ISynchronousClient
|
||||
}
|
||||
}
|
60
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ApiException.mustache
vendored
Normal file
60
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ApiException.mustache
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// API Exception
|
||||
/// </summary>
|
||||
{{>visibility}} class ApiException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the error code (HTTP status code)
|
||||
/// </summary>
|
||||
/// <value>The error code (HTTP status code).</value>
|
||||
public int ErrorCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the error content (body json object)
|
||||
/// </summary>
|
||||
/// <value>The error content (Http response body).</value>
|
||||
public object ErrorContent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP headers
|
||||
/// </summary>
|
||||
/// <value>HTTP headers</value>
|
||||
public Multimap<string, string> Headers { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiException"/> class.
|
||||
/// </summary>
|
||||
public ApiException() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="errorCode">HTTP status code.</param>
|
||||
/// <param name="message">Error message.</param>
|
||||
public ApiException(int errorCode, string message) : base(message)
|
||||
{
|
||||
this.ErrorCode = errorCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="errorCode">HTTP status code.</param>
|
||||
/// <param name="message">Error message.</param>
|
||||
/// <param name="errorContent">Error content.</param>
|
||||
/// <param name="headers">HTTP Headers.</param>
|
||||
public ApiException(int errorCode, string message, object errorContent = null, Multimap<string, string> headers = null) : base(message)
|
||||
{
|
||||
this.ErrorCode = errorCode;
|
||||
this.ErrorContent = errorContent;
|
||||
this.Headers = headers;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
158
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ApiResponse.mustache
vendored
Normal file
158
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ApiResponse.mustache
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a non-generic contract for the ApiResponse wrapper.
|
||||
/// </summary>
|
||||
public interface IApiResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// The data type of <see cref="Content"/>
|
||||
/// </summary>
|
||||
Type ResponseType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The content of this response
|
||||
/// </summary>
|
||||
Object Content { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the status code (HTTP status code)
|
||||
/// </summary>
|
||||
/// <value>The status code.</value>
|
||||
HttpStatusCode StatusCode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP headers
|
||||
/// </summary>
|
||||
/// <value>HTTP headers</value>
|
||||
Multimap<string, string> Headers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets any error text defined by the calling client.
|
||||
/// </summary>
|
||||
string ErrorText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets any cookies passed along on the response.
|
||||
/// </summary>
|
||||
List<Cookie> Cookies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The raw content of this response
|
||||
/// </summary>
|
||||
string RawContent { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API Response
|
||||
/// </summary>
|
||||
public class ApiResponse<T> : IApiResponse
|
||||
{
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the status code (HTTP status code)
|
||||
/// </summary>
|
||||
/// <value>The status code.</value>
|
||||
public HttpStatusCode StatusCode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP headers
|
||||
/// </summary>
|
||||
/// <value>HTTP headers</value>
|
||||
public Multimap<string, string> Headers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the data (parsed HTTP body)
|
||||
/// </summary>
|
||||
/// <value>The data.</value>
|
||||
public T Data { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets any error text defined by the calling client.
|
||||
/// </summary>
|
||||
public string ErrorText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets any cookies passed along on the response.
|
||||
/// </summary>
|
||||
public List<Cookie> Cookies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The content of this response
|
||||
/// </summary>
|
||||
public Type ResponseType
|
||||
{
|
||||
get { return typeof(T); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The data type of <see cref="Content"/>
|
||||
/// </summary>
|
||||
public object Content
|
||||
{
|
||||
get { return Data; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The raw content
|
||||
/// </summary>
|
||||
public string RawContent { get; }
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiResponse{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="statusCode">HTTP status code.</param>
|
||||
/// <param name="headers">HTTP headers.</param>
|
||||
/// <param name="data">Data (parsed HTTP body)</param>
|
||||
/// <param name="rawContent">Raw content.</param>
|
||||
public ApiResponse(HttpStatusCode statusCode, Multimap<string, string> headers, T data, string rawContent)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
Headers = headers;
|
||||
Data = data;
|
||||
RawContent = rawContent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiResponse{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="statusCode">HTTP status code.</param>
|
||||
/// <param name="headers">HTTP headers.</param>
|
||||
/// <param name="data">Data (parsed HTTP body)</param>
|
||||
public ApiResponse(HttpStatusCode statusCode, Multimap<string, string> headers, T data) : this(statusCode, headers, data, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiResponse{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="statusCode">HTTP status code.</param>
|
||||
/// <param name="data">Data (parsed HTTP body)</param>
|
||||
/// <param name="rawContent">Raw content.</param>
|
||||
public ApiResponse(HttpStatusCode statusCode, T data, string rawContent) : this(statusCode, null, data, rawContent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiResponse{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="statusCode">HTTP status code.</param>
|
||||
/// <param name="data">Data (parsed HTTP body)</param>
|
||||
public ApiResponse(HttpStatusCode statusCode, T data) : this(statusCode, data, null)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
}
|
||||
}
|
40
modules/openapi-generator/src/main/resources/csharp-netcore-functions/AssemblyInfo.mustache
vendored
Normal file
40
modules/openapi-generator/src/main/resources/csharp-netcore-functions/AssemblyInfo.mustache
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("{{packageTitle}}")]
|
||||
[assembly: AssemblyDescription("{{packageDescription}}")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("{{packageCompany}}")]
|
||||
[assembly: AssemblyProduct("{{packageProductName}}")]
|
||||
[assembly: AssemblyCopyright("{{packageCopyright}}")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("{{packageVersion}}")]
|
||||
[assembly: AssemblyFileVersion("{{packageVersion}}")]
|
||||
{{^supportsAsync}}
|
||||
// Settings which don't support asynchronous operations rely on non-public constructors
|
||||
// This is due to how RestSharp requires the type constraint `where T : new()` in places it probably shouldn't.
|
||||
[assembly: InternalsVisibleTo("RestSharp")]
|
||||
[assembly: InternalsVisibleTo("NewtonSoft.Json")]
|
||||
[assembly: InternalsVisibleTo("JsonSubTypes")]
|
||||
{{/supportsAsync}}
|
239
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ClientUtils.mustache
vendored
Normal file
239
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ClientUtils.mustache
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
{{#useCompareNetObjects}}
|
||||
using KellermanSoftware.CompareNetObjects;
|
||||
{{/useCompareNetObjects}}
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility functions providing some benefit to API client consumers.
|
||||
/// </summary>
|
||||
public static class ClientUtils
|
||||
{
|
||||
{{#useCompareNetObjects}}
|
||||
/// <summary>
|
||||
/// An instance of CompareLogic.
|
||||
/// </summary>
|
||||
public static CompareLogic compareLogic;
|
||||
|
||||
/// <summary>
|
||||
/// Static contstructor to initialise compareLogic.
|
||||
/// </summary>
|
||||
static ClientUtils()
|
||||
{
|
||||
compareLogic = new CompareLogic();
|
||||
}
|
||||
|
||||
{{/useCompareNetObjects}}
|
||||
/// <summary>
|
||||
/// Sanitize filename by removing the path
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename</param>
|
||||
/// <returns>Filename</returns>
|
||||
public static string SanitizeFilename(string filename)
|
||||
{
|
||||
Match match = Regex.Match(filename, @".*[/\\](.*)$");
|
||||
return match.Success ? match.Groups[1].Value : filename;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert params to key/value pairs.
|
||||
/// Use collectionFormat to properly format lists and collections.
|
||||
/// </summary>
|
||||
/// <param name="collectionFormat">The swagger-supported collection format, one of: csv, tsv, ssv, pipes, multi</param>
|
||||
/// <param name="name">Key name.</param>
|
||||
/// <param name="value">Value object.</param>
|
||||
/// <returns>A multimap of keys with 1..n associated values.</returns>
|
||||
public static Multimap<string, string> ParameterToMultiMap(string collectionFormat, string name, object value)
|
||||
{
|
||||
var parameters = new Multimap<string, string>();
|
||||
|
||||
if (value is ICollection collection && collectionFormat == "multi")
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
parameters.Add(name, ParameterToString(item));
|
||||
}
|
||||
}
|
||||
else if (value is IDictionary dictionary)
|
||||
{
|
||||
if(collectionFormat == "deepObject") {
|
||||
foreach (DictionaryEntry entry in dictionary)
|
||||
{
|
||||
parameters.Add(name + "[" + entry.Key + "]", ParameterToString(entry.Value));
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach (DictionaryEntry entry in dictionary)
|
||||
{
|
||||
parameters.Add(entry.Key.ToString(), ParameterToString(entry.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters.Add(name, ParameterToString(value));
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If parameter is DateTime, output in a formatted string (default ISO 8601), customizable with Configuration.DateTime.
|
||||
/// If parameter is a list, join the list with ",".
|
||||
/// Otherwise just return the string.
|
||||
/// </summary>
|
||||
/// <param name="obj">The parameter (header, path, query, form).</param>
|
||||
/// <param name="configuration">An optional configuration instance, providing formatting options used in processing.</param>
|
||||
/// <returns>Formatted string.</returns>
|
||||
public static string ParameterToString(object obj, IReadableConfiguration configuration = null)
|
||||
{
|
||||
if (obj is DateTime dateTime)
|
||||
// Return a formatted date string - Can be customized with Configuration.DateTimeFormat
|
||||
// Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o")
|
||||
// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8
|
||||
// For example: 2009-06-15T13:45:30.0000000
|
||||
return dateTime.ToString((configuration ?? GlobalConfiguration.Instance).DateTimeFormat);
|
||||
if (obj is DateTimeOffset dateTimeOffset)
|
||||
// Return a formatted date string - Can be customized with Configuration.DateTimeFormat
|
||||
// Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o")
|
||||
// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8
|
||||
// For example: 2009-06-15T13:45:30.0000000
|
||||
return dateTimeOffset.ToString((configuration ?? GlobalConfiguration.Instance).DateTimeFormat);
|
||||
if (obj is bool boolean)
|
||||
return boolean ? "true" : "false";
|
||||
if (obj is ICollection collection)
|
||||
return string.Join(",", collection.Cast<object>());
|
||||
|
||||
return Convert.ToString(obj, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// URL encode a string
|
||||
/// Credit/Ref: https://github.com/restsharp/RestSharp/blob/master/RestSharp/Extensions/StringExtensions.cs#L50
|
||||
/// </summary>
|
||||
/// <param name="input">string to be URL encoded</param>
|
||||
/// <returns>Byte array</returns>
|
||||
public static string UrlEncode(string input)
|
||||
{
|
||||
const int maxLength = 32766;
|
||||
|
||||
if (input == null)
|
||||
{
|
||||
throw new ArgumentNullException("input");
|
||||
}
|
||||
|
||||
if (input.Length <= maxLength)
|
||||
{
|
||||
return Uri.EscapeDataString(input);
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(input.Length * 2);
|
||||
int index = 0;
|
||||
|
||||
while (index < input.Length)
|
||||
{
|
||||
int length = Math.Min(input.Length - index, maxLength);
|
||||
string subString = input.Substring(index, length);
|
||||
|
||||
sb.Append(Uri.EscapeDataString(subString));
|
||||
index += subString.Length;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode string in base64 format.
|
||||
/// </summary>
|
||||
/// <param name="text">string to be encoded.</param>
|
||||
/// <returns>Encoded string.</returns>
|
||||
public static string Base64Encode(string text)
|
||||
{
|
||||
return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(text));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert stream to byte array
|
||||
/// </summary>
|
||||
/// <param name="inputStream">Input stream to be converted</param>
|
||||
/// <returns>Byte array</returns>
|
||||
public static byte[] ReadAsBytes(Stream inputStream)
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
inputStream.CopyTo(ms);
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Select the Content-Type header's value from the given content-type array:
|
||||
/// if JSON type exists in the given array, use it;
|
||||
/// otherwise use the first one defined in 'consumes'
|
||||
/// </summary>
|
||||
/// <param name="contentTypes">The Content-Type array to select from.</param>
|
||||
/// <returns>The Content-Type header to use.</returns>
|
||||
public static string SelectHeaderContentType(string[] contentTypes)
|
||||
{
|
||||
if (contentTypes.Length == 0)
|
||||
return null;
|
||||
|
||||
foreach (var contentType in contentTypes)
|
||||
{
|
||||
if (IsJsonMime(contentType))
|
||||
return contentType;
|
||||
}
|
||||
|
||||
return contentTypes[0]; // use the first content type specified in 'consumes'
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Select the Accept header's value from the given accepts array:
|
||||
/// if JSON exists in the given array, use it;
|
||||
/// otherwise use all of them (joining into a string)
|
||||
/// </summary>
|
||||
/// <param name="accepts">The accepts array to select from.</param>
|
||||
/// <returns>The Accept header to use.</returns>
|
||||
public static string SelectHeaderAccept(string[] accepts)
|
||||
{
|
||||
if (accepts.Length == 0)
|
||||
return null;
|
||||
|
||||
if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase))
|
||||
return "application/json";
|
||||
|
||||
return string.Join(",", accepts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides a case-insensitive check that a provided content type is a known JSON-like content type.
|
||||
/// </summary>
|
||||
public static readonly Regex JsonRegex = new Regex("(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$");
|
||||
|
||||
/// <summary>
|
||||
/// Check if the given MIME is a JSON MIME.
|
||||
/// JSON MIME examples:
|
||||
/// application/json
|
||||
/// application/json; charset=UTF8
|
||||
/// APPLICATION/JSON
|
||||
/// application/vnd.company+json
|
||||
/// </summary>
|
||||
/// <param name="mime">MIME</param>
|
||||
/// <returns>Returns True if MIME type is json.</returns>
|
||||
public static bool IsJsonMime(string mime)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(mime)) return false;
|
||||
|
||||
return JsonRegex.IsMatch(mime) || mime.Equals("application/json-patch+json");
|
||||
}
|
||||
}
|
||||
}
|
574
modules/openapi-generator/src/main/resources/csharp-netcore-functions/Configuration.mustache
vendored
Normal file
574
modules/openapi-generator/src/main/resources/csharp-netcore-functions/Configuration.mustache
vendored
Normal file
@ -0,0 +1,574 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
{{^net35}}
|
||||
using System.Collections.Concurrent;
|
||||
{{/net35}}
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a set of configuration settings
|
||||
/// </summary>
|
||||
{{>visibility}} class Configuration : IReadableConfiguration
|
||||
{
|
||||
#region Constants
|
||||
|
||||
/// <summary>
|
||||
/// Version of the package.
|
||||
/// </summary>
|
||||
/// <value>Version of the package.</value>
|
||||
public const string Version = "{{packageVersion}}";
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for ISO 8601 DateTime Format
|
||||
/// </summary>
|
||||
/// <remarks>See https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8 for more information.</remarks>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public const string ISO8601_DATETIME_FORMAT = "o";
|
||||
|
||||
#endregion Constants
|
||||
|
||||
#region Static Members
|
||||
|
||||
/// <summary>
|
||||
/// Default creation of exceptions for a given method name and response object
|
||||
/// </summary>
|
||||
public static readonly ExceptionFactory DefaultExceptionFactory = (methodName, response) =>
|
||||
{
|
||||
var status = (int)response.StatusCode;
|
||||
if (status >= 400)
|
||||
{
|
||||
return new ApiException(status,
|
||||
string.Format("Error calling {0}: {1}", methodName, response.RawContent),
|
||||
response.RawContent, response.Headers);
|
||||
}
|
||||
{{^netStandard}}
|
||||
if (status == 0)
|
||||
{
|
||||
return new ApiException(status,
|
||||
string.Format("Error calling {0}: {1}", methodName, response.ErrorText), response.ErrorText);
|
||||
}
|
||||
{{/netStandard}}
|
||||
return null;
|
||||
};
|
||||
|
||||
#endregion Static Members
|
||||
|
||||
#region Private Members
|
||||
|
||||
/// <summary>
|
||||
/// Defines the base path of the target API server.
|
||||
/// Example: http://localhost:3000/v1/
|
||||
/// </summary>
|
||||
private string _basePath;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the API key based on the authentication name.
|
||||
/// This is the key and value comprising the "secret" for acessing an API.
|
||||
/// </summary>
|
||||
/// <value>The API key.</value>
|
||||
private IDictionary<string, string> _apiKey;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name.
|
||||
/// </summary>
|
||||
/// <value>The prefix of the API key.</value>
|
||||
private IDictionary<string, string> _apiKeyPrefix;
|
||||
|
||||
private string _dateTimeFormat = ISO8601_DATETIME_FORMAT;
|
||||
private string _tempFolderPath = Path.GetTempPath();
|
||||
{{#servers.0}}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the servers defined in the OpenAPI spec.
|
||||
/// </summary>
|
||||
/// <value>The servers</value>
|
||||
private IList<IReadOnlyDictionary<string, object>> _servers;
|
||||
{{/servers.0}}
|
||||
{{#hasHttpSignatureMethods}}
|
||||
|
||||
/// <summary>
|
||||
/// HttpSigning configuration
|
||||
/// </summary>
|
||||
private HttpSigningConfiguration _HttpSigningConfiguration = null;
|
||||
{{/hasHttpSignatureMethods}}
|
||||
#endregion Private Members
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Configuration" /> class
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("ReSharper", "VirtualMemberCallInConstructor")]
|
||||
public Configuration()
|
||||
{
|
||||
Proxy = null;
|
||||
UserAgent = "{{#httpUserAgent}}{{.}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{packageVersion}}/csharp{{/httpUserAgent}}";
|
||||
BasePath = "{{{basePath}}}";
|
||||
DefaultHeaders = new {{^net35}}Concurrent{{/net35}}Dictionary<string, string>();
|
||||
ApiKey = new {{^net35}}Concurrent{{/net35}}Dictionary<string, string>();
|
||||
ApiKeyPrefix = new {{^net35}}Concurrent{{/net35}}Dictionary<string, string>();
|
||||
{{#servers}}
|
||||
{{#-first}}
|
||||
Servers = new List<IReadOnlyDictionary<string, object>>()
|
||||
{
|
||||
{{/-first}}
|
||||
{
|
||||
new Dictionary<string, object> {
|
||||
{"url", "{{{url}}}"},
|
||||
{"description", "{{{description}}}{{^description}}No description provided{{/description}}"},
|
||||
{{#variables}}
|
||||
{{#-first}}
|
||||
{
|
||||
"variables", new Dictionary<string, object> {
|
||||
{{/-first}}
|
||||
{
|
||||
"{{{name}}}", new Dictionary<string, object> {
|
||||
{"description", "{{{description}}}{{^description}}No description provided{{/description}}"},
|
||||
{"default_value", "{{{defaultValue}}}"},
|
||||
{{#enumValues}}
|
||||
{{#-first}}
|
||||
{
|
||||
"enum_values", new List<string>() {
|
||||
{{/-first}}
|
||||
"{{{.}}}"{{^-last}},{{/-last}}
|
||||
{{#-last}}
|
||||
}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/enumValues}}
|
||||
}
|
||||
}{{^-last}},{{/-last}}
|
||||
{{#-last}}
|
||||
}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/variables}}
|
||||
}
|
||||
}{{^-last}},{{/-last}}
|
||||
{{#-last}}
|
||||
};
|
||||
{{/-last}}
|
||||
{{/servers}}
|
||||
|
||||
// Setting Timeout has side effects (forces ApiClient creation).
|
||||
Timeout = 100000;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Configuration" /> class
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("ReSharper", "VirtualMemberCallInConstructor")]
|
||||
public Configuration(
|
||||
IDictionary<string, string> defaultHeaders,
|
||||
IDictionary<string, string> apiKey,
|
||||
IDictionary<string, string> apiKeyPrefix,
|
||||
string basePath = "{{{basePath}}}") : this()
|
||||
{
|
||||
if (string.{{^net35}}IsNullOrWhiteSpace{{/net35}}{{#net35}}IsNullOrEmpty{{/net35}}(basePath))
|
||||
throw new ArgumentException("The provided basePath is invalid.", "basePath");
|
||||
if (defaultHeaders == null)
|
||||
throw new ArgumentNullException("defaultHeaders");
|
||||
if (apiKey == null)
|
||||
throw new ArgumentNullException("apiKey");
|
||||
if (apiKeyPrefix == null)
|
||||
throw new ArgumentNullException("apiKeyPrefix");
|
||||
|
||||
BasePath = basePath;
|
||||
|
||||
foreach (var keyValuePair in defaultHeaders)
|
||||
{
|
||||
DefaultHeaders.Add(keyValuePair);
|
||||
}
|
||||
|
||||
foreach (var keyValuePair in apiKey)
|
||||
{
|
||||
ApiKey.Add(keyValuePair);
|
||||
}
|
||||
|
||||
foreach (var keyValuePair in apiKeyPrefix)
|
||||
{
|
||||
ApiKeyPrefix.Add(keyValuePair);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the base path for API access.
|
||||
/// </summary>
|
||||
public virtual string BasePath {
|
||||
get { return _basePath; }
|
||||
set { _basePath = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default header.
|
||||
/// </summary>
|
||||
[Obsolete("Use DefaultHeaders instead.")]
|
||||
public virtual IDictionary<string, string> DefaultHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
return DefaultHeaders;
|
||||
}
|
||||
set
|
||||
{
|
||||
DefaultHeaders = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default headers.
|
||||
/// </summary>
|
||||
public virtual IDictionary<string, string> DefaultHeaders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP timeout (milliseconds) of ApiClient. Default to 100000 milliseconds.
|
||||
/// </summary>
|
||||
public virtual int Timeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the proxy
|
||||
/// </summary>
|
||||
/// <value>Proxy.</value>
|
||||
public virtual WebProxy Proxy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP user agent.
|
||||
/// </summary>
|
||||
/// <value>Http user agent.</value>
|
||||
public virtual string UserAgent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the username (HTTP basic authentication).
|
||||
/// </summary>
|
||||
/// <value>The username.</value>
|
||||
public virtual string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password (HTTP basic authentication).
|
||||
/// </summary>
|
||||
/// <value>The password.</value>
|
||||
public virtual string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the API key with prefix.
|
||||
/// </summary>
|
||||
/// <param name="apiKeyIdentifier">API key identifier (authentication scheme).</param>
|
||||
/// <returns>API key with prefix.</returns>
|
||||
public string GetApiKeyWithPrefix(string apiKeyIdentifier)
|
||||
{
|
||||
string apiKeyValue;
|
||||
ApiKey.TryGetValue(apiKeyIdentifier, out apiKeyValue);
|
||||
string apiKeyPrefix;
|
||||
if (ApiKeyPrefix.TryGetValue(apiKeyIdentifier, out apiKeyPrefix))
|
||||
{
|
||||
return apiKeyPrefix + " " + apiKeyValue;
|
||||
}
|
||||
|
||||
return apiKeyValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets certificate collection to be sent with requests.
|
||||
/// </summary>
|
||||
/// <value>X509 Certificate collection.</value>
|
||||
public X509CertificateCollection ClientCertificates { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the access token for OAuth2 authentication.
|
||||
///
|
||||
/// This helper property simplifies code generation.
|
||||
/// </summary>
|
||||
/// <value>The access token.</value>
|
||||
public virtual string AccessToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the temporary folder path to store the files downloaded from the server.
|
||||
/// </summary>
|
||||
/// <value>Folder path.</value>
|
||||
public virtual string TempFolderPath
|
||||
{
|
||||
get { return _tempFolderPath; }
|
||||
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
_tempFolderPath = Path.GetTempPath();
|
||||
return;
|
||||
}
|
||||
|
||||
// create the directory if it does not exist
|
||||
if (!Directory.Exists(value))
|
||||
{
|
||||
Directory.CreateDirectory(value);
|
||||
}
|
||||
|
||||
// check if the path contains directory separator at the end
|
||||
if (value[value.Length - 1] == Path.DirectorySeparatorChar)
|
||||
{
|
||||
_tempFolderPath = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_tempFolderPath = value + Path.DirectorySeparatorChar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date time format used when serializing in the ApiClient
|
||||
/// By default, it's set to ISO 8601 - "o", for others see:
|
||||
/// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
|
||||
/// and https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
|
||||
/// No validation is done to ensure that the string you're providing is valid
|
||||
/// </summary>
|
||||
/// <value>The DateTimeFormat string</value>
|
||||
public virtual string DateTimeFormat
|
||||
{
|
||||
get { return _dateTimeFormat; }
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
// Never allow a blank or null string, go back to the default
|
||||
_dateTimeFormat = ISO8601_DATETIME_FORMAT;
|
||||
return;
|
||||
}
|
||||
|
||||
// Caution, no validation when you choose date time format other than ISO 8601
|
||||
// Take a look at the above links
|
||||
_dateTimeFormat = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name.
|
||||
///
|
||||
/// Whatever you set here will be prepended to the value defined in AddApiKey.
|
||||
///
|
||||
/// An example invocation here might be:
|
||||
/// <example>
|
||||
/// ApiKeyPrefix["Authorization"] = "Bearer";
|
||||
/// </example>
|
||||
/// … where ApiKey["Authorization"] would then be used to set the value of your bearer token.
|
||||
///
|
||||
/// <remarks>
|
||||
/// OAuth2 workflows should set tokens via AccessToken.
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
/// <value>The prefix of the API key.</value>
|
||||
public virtual IDictionary<string, string> ApiKeyPrefix
|
||||
{
|
||||
get { return _apiKeyPrefix; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new InvalidOperationException("ApiKeyPrefix collection may not be null.");
|
||||
}
|
||||
_apiKeyPrefix = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the API key based on the authentication name.
|
||||
/// </summary>
|
||||
/// <value>The API key.</value>
|
||||
public virtual IDictionary<string, string> ApiKey
|
||||
{
|
||||
get { return _apiKey; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new InvalidOperationException("ApiKey collection may not be null.");
|
||||
}
|
||||
_apiKey = value;
|
||||
}
|
||||
}
|
||||
{{#servers.0}}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the servers.
|
||||
/// </summary>
|
||||
/// <value>The servers.</value>
|
||||
public virtual IList<IReadOnlyDictionary<string, object>> Servers
|
||||
{
|
||||
get { return _servers; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new InvalidOperationException("Servers may not be null.");
|
||||
}
|
||||
_servers = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns URL based on server settings without providing values
|
||||
/// for the variables
|
||||
/// </summary>
|
||||
/// <param name="index">Array index of the server settings.</param>
|
||||
/// <return>The server URL.</return>
|
||||
public string GetServerUrl(int index)
|
||||
{
|
||||
return GetServerUrl(index, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns URL based on server settings.
|
||||
/// </summary>
|
||||
/// <param name="index">Array index of the server settings.</param>
|
||||
/// <param name="inputVariables">Dictionary of the variables and the corresponding values.</param>
|
||||
/// <return>The server URL.</return>
|
||||
public string GetServerUrl(int index, Dictionary<string, string> inputVariables)
|
||||
{
|
||||
if (index < 0 || index >= Servers.Count)
|
||||
{
|
||||
throw new InvalidOperationException($"Invalid index {index} when selecting the server. Must be less than {Servers.Count}.");
|
||||
}
|
||||
|
||||
if (inputVariables == null)
|
||||
{
|
||||
inputVariables = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
IReadOnlyDictionary<string, object> server = Servers[index];
|
||||
string url = (string)server["url"];
|
||||
|
||||
// go through variable and assign a value
|
||||
foreach (KeyValuePair<string, object> variable in (IReadOnlyDictionary<string, object>)server["variables"])
|
||||
{
|
||||
|
||||
IReadOnlyDictionary<string, object> serverVariables = (IReadOnlyDictionary<string, object>)(variable.Value);
|
||||
|
||||
if (inputVariables.ContainsKey(variable.Key))
|
||||
{
|
||||
if (((List<string>)serverVariables["enum_values"]).Contains(inputVariables[variable.Key]))
|
||||
{
|
||||
url = url.Replace("{" + variable.Key + "}", inputVariables[variable.Key]);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"The variable `{variable.Key}` in the server URL has invalid value #{inputVariables[variable.Key]}. Must be {(List<string>)serverVariables["enum_values"]}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// use defualt value
|
||||
url = url.Replace("{" + variable.Key + "}", (string)serverVariables["default_value"]);
|
||||
}
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
{{/servers.0}}
|
||||
{{#hasHttpSignatureMethods}}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and Sets the HttpSigningConfiuration
|
||||
/// </summary>
|
||||
public HttpSigningConfiguration HttpSigningConfiguration
|
||||
{
|
||||
get { return _HttpSigningConfiguration; }
|
||||
set { _HttpSigningConfiguration = value; }
|
||||
}
|
||||
{{/hasHttpSignatureMethods}}
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string with essential information for debugging.
|
||||
/// </summary>
|
||||
public static string ToDebugReport()
|
||||
{
|
||||
string report = "C# SDK ({{{packageName}}}) Debug Report:\n";
|
||||
report += " OS: " + System.Environment.OSVersion + "\n";
|
||||
report += " .NET Framework Version: " + System.Environment.Version + "\n";
|
||||
report += " Version of the API: {{{version}}}\n";
|
||||
report += " SDK Package Version: {{{packageVersion}}}\n";
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Api Key Header.
|
||||
/// </summary>
|
||||
/// <param name="key">Api Key name.</param>
|
||||
/// <param name="value">Api Key value.</param>
|
||||
/// <returns></returns>
|
||||
public void AddApiKey(string key, string value)
|
||||
{
|
||||
ApiKey[key] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the API key prefix.
|
||||
/// </summary>
|
||||
/// <param name="key">Api Key name.</param>
|
||||
/// <param name="value">Api Key value.</param>
|
||||
public void AddApiKeyPrefix(string key, string value)
|
||||
{
|
||||
ApiKeyPrefix[key] = value;
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
|
||||
#region Static Members
|
||||
/// <summary>
|
||||
/// Merge configurations.
|
||||
/// </summary>
|
||||
/// <param name="first">First configuration.</param>
|
||||
/// <param name="second">Second configuration.</param>
|
||||
/// <return>Merged configuration.</return>
|
||||
public static IReadableConfiguration MergeConfigurations(IReadableConfiguration first, IReadableConfiguration second)
|
||||
{
|
||||
if (second == null) return first ?? GlobalConfiguration.Instance;
|
||||
|
||||
Dictionary<string, string> apiKey = first.ApiKey.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||
Dictionary<string, string> apiKeyPrefix = first.ApiKeyPrefix.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||
Dictionary<string, string> defaultHeaders = first.DefaultHeaders.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||
|
||||
foreach (var kvp in second.ApiKey) apiKey[kvp.Key] = kvp.Value;
|
||||
foreach (var kvp in second.ApiKeyPrefix) apiKeyPrefix[kvp.Key] = kvp.Value;
|
||||
foreach (var kvp in second.DefaultHeaders) defaultHeaders[kvp.Key] = kvp.Value;
|
||||
|
||||
var config = new Configuration
|
||||
{
|
||||
ApiKey = apiKey,
|
||||
ApiKeyPrefix = apiKeyPrefix,
|
||||
DefaultHeaders = defaultHeaders,
|
||||
BasePath = second.BasePath ?? first.BasePath,
|
||||
Timeout = second.Timeout,
|
||||
Proxy = second.Proxy ?? first.Proxy,
|
||||
UserAgent = second.UserAgent ?? first.UserAgent,
|
||||
Username = second.Username ?? first.Username,
|
||||
Password = second.Password ?? first.Password,
|
||||
AccessToken = second.AccessToken ?? first.AccessToken,
|
||||
{{#hasHttpSignatureMethods}}
|
||||
HttpSigningConfiguration = second.HttpSigningConfiguration ?? first.HttpSigningConfiguration,
|
||||
{{/hasHttpSignatureMethods}}
|
||||
TempFolderPath = second.TempFolderPath ?? first.TempFolderPath,
|
||||
DateTimeFormat = second.DateTimeFormat ?? first.DateTimeFormat
|
||||
};
|
||||
return config;
|
||||
}
|
||||
#endregion Static Members
|
||||
}
|
||||
}
|
14
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ExceptionFactory.mustache
vendored
Normal file
14
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ExceptionFactory.mustache
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// A delegate to ExceptionFactory method
|
||||
/// </summary>
|
||||
/// <param name="methodName">Method name</param>
|
||||
/// <param name="response">Response</param>
|
||||
/// <returns>Exceptions</returns>
|
||||
{{>visibility}} delegate Exception ExceptionFactory(string methodName, IApiResponse response);
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="GlobalConfiguration"/> provides a compile-time extension point for globally configuring
|
||||
/// API Clients.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A customized implementation via partial class may reside in another file and may
|
||||
/// be excluded from automatic generation via a .openapi-generator-ignore file.
|
||||
/// </remarks>
|
||||
public partial class GlobalConfiguration : Configuration
|
||||
{
|
||||
#region Private Members
|
||||
|
||||
private static readonly object GlobalConfigSync = new { };
|
||||
private static IReadableConfiguration _globalConfiguration;
|
||||
|
||||
#endregion Private Members
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc />
|
||||
private GlobalConfiguration()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public GlobalConfiguration(IDictionary<string, string> defaultHeader, IDictionary<string, string> apiKey, IDictionary<string, string> apiKeyPrefix, string basePath = "http://localhost:3000/api") : base(defaultHeader, apiKey, apiKeyPrefix, basePath)
|
||||
{
|
||||
}
|
||||
|
||||
static GlobalConfiguration()
|
||||
{
|
||||
Instance = new GlobalConfiguration();
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default Configuration.
|
||||
/// </summary>
|
||||
/// <value>Configuration.</value>
|
||||
public static IReadableConfiguration Instance
|
||||
{
|
||||
get { return _globalConfiguration; }
|
||||
set
|
||||
{
|
||||
lock (GlobalConfigSync)
|
||||
{
|
||||
_globalConfiguration = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
modules/openapi-generator/src/main/resources/csharp-netcore-functions/HttpMethod.mustache
vendored
Normal file
25
modules/openapi-generator/src/main/resources/csharp-netcore-functions/HttpMethod.mustache
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
{{>partial_header}}
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Http methods supported by swagger
|
||||
/// </summary>
|
||||
public enum HttpMethod
|
||||
{
|
||||
/// <summary>HTTP GET request.</summary>
|
||||
Get,
|
||||
/// <summary>HTTP POST request.</summary>
|
||||
Post,
|
||||
/// <summary>HTTP PUT request.</summary>
|
||||
Put,
|
||||
/// <summary>HTTP DELETE request.</summary>
|
||||
Delete,
|
||||
/// <summary>HTTP HEAD request.</summary>
|
||||
Head,
|
||||
/// <summary>HTTP OPTIONS request.</summary>
|
||||
Options,
|
||||
/// <summary>HTTP PATCH request.</summary>
|
||||
Patch
|
||||
}
|
||||
}
|
@ -0,0 +1,757 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for HttpSigning auth related parameter and methods
|
||||
/// </summary>
|
||||
public class HttpSigningConfiguration
|
||||
{
|
||||
#region
|
||||
/// <summary>
|
||||
/// Initailize the HashAlgorithm and SigningAlgorithm to default value
|
||||
/// </summary>
|
||||
public HttpSigningConfiguration()
|
||||
{
|
||||
HashAlgorithm = HashAlgorithmName.SHA256;
|
||||
SigningAlgorithm = "PKCS1-v15";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
///Gets the Api keyId
|
||||
/// </summary>
|
||||
public string KeyId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Key file path
|
||||
/// </summary>
|
||||
public string KeyFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key pass phrase for password protected key
|
||||
/// </summary>
|
||||
public SecureString KeyPassPhrase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTP signing header
|
||||
/// </summary>
|
||||
public List<string> HttpSigningHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash algorithm sha256 or sha512
|
||||
/// </summary>
|
||||
public HashAlgorithmName HashAlgorithm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the signing algorithm
|
||||
/// </summary>
|
||||
public string SigningAlgorithm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Signature validaty period in seconds
|
||||
/// </summary>
|
||||
public int SignatureValidityPeriod { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region enum
|
||||
private enum PrivateKeyType
|
||||
{
|
||||
None = 0,
|
||||
RSA = 1,
|
||||
ECDSA = 2,
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
/// <summary>
|
||||
/// Gets the Headers for HttpSigning
|
||||
/// </summary>
|
||||
/// <param name="basePath">Base path</param>
|
||||
/// <param name="method">HTTP method</param>
|
||||
/// <param name="path">Path</param>
|
||||
/// <param name="requestOptions">Request options</param>
|
||||
/// <returns></returns>
|
||||
internal Dictionary<string, string> GetHttpSignedHeader(string basePath,string method, string path, RequestOptions requestOptions)
|
||||
{
|
||||
const string HEADER_REQUEST_TARGET = "(request-target)";
|
||||
//The time when the HTTP signature expires. The API server should reject HTTP requests
|
||||
//that have expired.
|
||||
const string HEADER_EXPIRES = "(expires)";
|
||||
//The 'Date' header.
|
||||
const string HEADER_DATE = "Date";
|
||||
//The 'Host' header.
|
||||
const string HEADER_HOST = "Host";
|
||||
//The time when the HTTP signature was generated.
|
||||
const string HEADER_CREATED = "(created)";
|
||||
//When the 'Digest' header is included in the HTTP signature, the client automatically
|
||||
//computes the digest of the HTTP request body, per RFC 3230.
|
||||
const string HEADER_DIGEST = "Digest";
|
||||
//The 'Authorization' header is automatically generated by the client. It includes
|
||||
//the list of signed headers and a base64-encoded signature.
|
||||
const string HEADER_AUTHORIZATION = "Authorization";
|
||||
|
||||
//Hash table to store singed headers
|
||||
var HttpSignedRequestHeader = new Dictionary<string, string>();
|
||||
var HttpSignatureHeader = new Dictionary<string, string>();
|
||||
|
||||
if (HttpSigningHeader.Count == 0)
|
||||
{
|
||||
HttpSigningHeader.Add("(created)");
|
||||
}
|
||||
|
||||
if (requestOptions.PathParameters != null)
|
||||
{
|
||||
foreach (var pathParam in requestOptions.PathParameters)
|
||||
{
|
||||
var tempPath = path.Replace(pathParam.Key, "0");
|
||||
path = string.Format(tempPath, pathParam.Value);
|
||||
}
|
||||
}
|
||||
|
||||
var httpValues = HttpUtility.ParseQueryString(string.Empty);
|
||||
foreach (var parameter in requestOptions.QueryParameters)
|
||||
{
|
||||
#if (NETCOREAPP)
|
||||
if (parameter.Value.Count > 1)
|
||||
{ // array
|
||||
foreach (var value in parameter.Value)
|
||||
{
|
||||
httpValues.Add(HttpUtility.UrlEncode(parameter.Key) + "[]", value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
httpValues.Add(HttpUtility.UrlEncode(parameter.Key), parameter.Value[0]);
|
||||
}
|
||||
#else
|
||||
if (parameter.Value.Count > 1)
|
||||
{ // array
|
||||
foreach (var value in parameter.Value)
|
||||
{
|
||||
httpValues.Add(parameter.Key + "[]", value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
httpValues.Add(parameter.Key, parameter.Value[0]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
var uriBuilder = new UriBuilder(string.Concat(basePath, path));
|
||||
uriBuilder.Query = httpValues.ToString().Replace("+", "%20");
|
||||
|
||||
var dateTime = DateTime.Now;
|
||||
string Digest = string.Empty;
|
||||
|
||||
//get the body
|
||||
string requestBody = string.Empty;
|
||||
if (requestOptions.Data != null)
|
||||
{
|
||||
var serializerSettings = new JsonSerializerSettings();
|
||||
requestBody = JsonConvert.SerializeObject(requestOptions.Data, serializerSettings);
|
||||
}
|
||||
|
||||
if (HashAlgorithm == HashAlgorithmName.SHA256)
|
||||
{
|
||||
var bodyDigest = GetStringHash(HashAlgorithm.ToString(), requestBody);
|
||||
Digest = string.Format("SHA-256={0}", Convert.ToBase64String(bodyDigest));
|
||||
}
|
||||
else if (HashAlgorithm == HashAlgorithmName.SHA512)
|
||||
{
|
||||
var bodyDigest = GetStringHash(HashAlgorithm.ToString(), requestBody);
|
||||
Digest = string.Format("SHA-512={0}", Convert.ToBase64String(bodyDigest));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(string.Format("{0} not supported", HashAlgorithm));
|
||||
}
|
||||
|
||||
|
||||
foreach (var header in HttpSigningHeader)
|
||||
{
|
||||
if (header.Equals(HEADER_REQUEST_TARGET))
|
||||
{
|
||||
var targetUrl = string.Format("{0} {1}{2}", method.ToLower(), uriBuilder.Path, uriBuilder.Query);
|
||||
HttpSignatureHeader.Add(header.ToLower(), targetUrl);
|
||||
}
|
||||
else if (header.Equals(HEADER_EXPIRES))
|
||||
{
|
||||
var expireDateTime = dateTime.AddSeconds(SignatureValidityPeriod);
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(expireDateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DATE))
|
||||
{
|
||||
var utcDateTime = dateTime.ToString("r").ToString();
|
||||
HttpSignatureHeader.Add(header.ToLower(), utcDateTime);
|
||||
HttpSignedRequestHeader.Add(HEADER_DATE, utcDateTime);
|
||||
}
|
||||
else if (header.Equals(HEADER_HOST))
|
||||
{
|
||||
HttpSignatureHeader.Add(header.ToLower(), uriBuilder.Host);
|
||||
HttpSignedRequestHeader.Add(HEADER_HOST, uriBuilder.Host);
|
||||
}
|
||||
else if (header.Equals(HEADER_CREATED))
|
||||
{
|
||||
HttpSignatureHeader.Add(header.ToLower(), GetUnixTime(dateTime).ToString());
|
||||
}
|
||||
else if (header.Equals(HEADER_DIGEST))
|
||||
{
|
||||
HttpSignedRequestHeader.Add(HEADER_DIGEST, Digest);
|
||||
HttpSignatureHeader.Add(header.ToLower(), Digest);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isHeaderFound = false;
|
||||
foreach (var item in requestOptions.HeaderParameters)
|
||||
{
|
||||
if (string.Equals(item.Key, header, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
HttpSignatureHeader.Add(header.ToLower(), item.Value.ToString());
|
||||
isHeaderFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isHeaderFound)
|
||||
{
|
||||
throw new Exception(string.Format("Cannot sign HTTP request.Request does not contain the {0} header.",header));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
var headersKeysString = string.Join(" ", HttpSignatureHeader.Keys);
|
||||
var headerValuesList = new List<string>();
|
||||
|
||||
foreach (var keyVal in HttpSignatureHeader)
|
||||
{
|
||||
headerValuesList.Add(string.Format("{0}: {1}", keyVal.Key, keyVal.Value));
|
||||
|
||||
}
|
||||
//Concatinate headers value separated by new line
|
||||
var headerValuesString = string.Join("\n", headerValuesList);
|
||||
var signatureStringHash = GetStringHash(HashAlgorithm.ToString(), headerValuesString);
|
||||
string headerSignatureStr = null;
|
||||
var keyType = GetKeyType(KeyFilePath);
|
||||
|
||||
if (keyType == PrivateKeyType.RSA)
|
||||
{
|
||||
headerSignatureStr = GetRSASignature(signatureStringHash);
|
||||
}
|
||||
else if (keyType == PrivateKeyType.ECDSA)
|
||||
{
|
||||
headerSignatureStr = GetECDSASignature(signatureStringHash);
|
||||
}
|
||||
var cryptographicScheme = "hs2019";
|
||||
var authorizationHeaderValue = string.Format("Signature keyId=\"{0}\",algorithm=\"{1}\"",
|
||||
KeyId, cryptographicScheme);
|
||||
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_CREATED))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",created={0}", HttpSignatureHeader[HEADER_CREATED]);
|
||||
}
|
||||
|
||||
if (HttpSignatureHeader.ContainsKey(HEADER_EXPIRES))
|
||||
{
|
||||
authorizationHeaderValue += string.Format(",expires={0}", HttpSignatureHeader[HEADER_EXPIRES]);
|
||||
}
|
||||
|
||||
authorizationHeaderValue += string.Format(",headers=\"{0}\",signature=\"{1}\"",
|
||||
headersKeysString, headerSignatureStr);
|
||||
|
||||
HttpSignedRequestHeader.Add(HEADER_AUTHORIZATION, authorizationHeaderValue);
|
||||
|
||||
return HttpSignedRequestHeader;
|
||||
}
|
||||
|
||||
private byte[] GetStringHash(string hashName, string stringToBeHashed)
|
||||
{
|
||||
var hashAlgorithm = System.Security.Cryptography.HashAlgorithm.Create(hashName);
|
||||
var bytes = Encoding.UTF8.GetBytes(stringToBeHashed);
|
||||
var stringHash = hashAlgorithm.ComputeHash(bytes);
|
||||
return stringHash;
|
||||
}
|
||||
|
||||
private int GetUnixTime(DateTime date2)
|
||||
{
|
||||
DateTime date1 = new DateTime(1970, 01, 01);
|
||||
TimeSpan timeSpan = date2 - date1;
|
||||
return (int)timeSpan.TotalSeconds;
|
||||
}
|
||||
|
||||
private string GetRSASignature(byte[] stringToSign)
|
||||
{
|
||||
RSA rsa = GetRSAProviderFromPemFile(KeyFilePath, KeyPassPhrase);
|
||||
if (SigningAlgorithm == "RSASSA-PSS")
|
||||
{
|
||||
var signedbytes = rsa.SignHash(stringToSign, HashAlgorithm, RSASignaturePadding.Pss);
|
||||
return Convert.ToBase64String(signedbytes);
|
||||
}
|
||||
else if (SigningAlgorithm == "PKCS1-v15")
|
||||
{
|
||||
var signedbytes = rsa.SignHash(stringToSign, HashAlgorithm, RSASignaturePadding.Pkcs1);
|
||||
return Convert.ToBase64String(signedbytes);
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ECDSA signature
|
||||
/// </summary>
|
||||
/// <param name="dataToSign"></param>
|
||||
/// <returns></returns>
|
||||
private string GetECDSASignature(byte[] dataToSign)
|
||||
{
|
||||
if (!File.Exists(KeyFilePath))
|
||||
{
|
||||
throw new Exception("key file path does not exist.");
|
||||
}
|
||||
|
||||
var ecKeyHeader = "-----BEGIN EC PRIVATE KEY-----";
|
||||
var ecKeyFooter = "-----END EC PRIVATE KEY-----";
|
||||
var keyStr = File.ReadAllText(KeyFilePath);
|
||||
var ecKeyBase64String = keyStr.Replace(ecKeyHeader, "").Replace(ecKeyFooter, "").Trim();
|
||||
var keyBytes = System.Convert.FromBase64String(ecKeyBase64String);
|
||||
var ecdsa = ECDsa.Create();
|
||||
|
||||
#if (NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0)
|
||||
var byteCount = 0;
|
||||
if (KeyPassPhrase != null)
|
||||
{
|
||||
IntPtr unmanagedString = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
// convert secure string to byte array
|
||||
unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(KeyPassPhrase);
|
||||
ecdsa.ImportEncryptedPkcs8PrivateKey(Encoding.UTF8.GetBytes(Marshal.PtrToStringUni(unmanagedString)), keyBytes, out byteCount);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (unmanagedString != IntPtr.Zero)
|
||||
{
|
||||
Marshal.ZeroFreeBSTR(unmanagedString);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ecdsa.ImportPkcs8PrivateKey(keyBytes, out byteCount);
|
||||
}
|
||||
var signedBytes = ecdsa.SignHash(dataToSign);
|
||||
var derBytes = ConvertToECDSAANS1Format(signedBytes);
|
||||
var signedString = System.Convert.ToBase64String(derBytes);
|
||||
|
||||
return signedString;
|
||||
#else
|
||||
throw new Exception("ECDSA signing is supported only on NETCOREAPP3_0 and above");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private byte[] ConvertToECDSAANS1Format(byte[] signedBytes)
|
||||
{
|
||||
var derBytes = new List<byte>();
|
||||
byte derLength = 68; //default lenght for ECDSA code signinged bit 0x44
|
||||
byte rbytesLength = 32; //R length 0x20
|
||||
byte sbytesLength = 32; //S length 0x20
|
||||
var rBytes = new List<byte>();
|
||||
var sBytes = new List<byte>();
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
rBytes.Add(signedBytes[i]);
|
||||
}
|
||||
for (int i = 32; i < 64; i++)
|
||||
{
|
||||
sBytes.Add(signedBytes[i]);
|
||||
}
|
||||
|
||||
if (rBytes[0] > 0x7F)
|
||||
{
|
||||
derLength++;
|
||||
rbytesLength++;
|
||||
var tempBytes = new List<byte>();
|
||||
tempBytes.AddRange(rBytes);
|
||||
rBytes.Clear();
|
||||
rBytes.Add(0x00);
|
||||
rBytes.AddRange(tempBytes);
|
||||
}
|
||||
|
||||
if (sBytes[0] > 0x7F)
|
||||
{
|
||||
derLength++;
|
||||
sbytesLength++;
|
||||
var tempBytes = new List<byte>();
|
||||
tempBytes.AddRange(sBytes);
|
||||
sBytes.Clear();
|
||||
sBytes.Add(0x00);
|
||||
sBytes.AddRange(tempBytes);
|
||||
|
||||
}
|
||||
|
||||
derBytes.Add(48); //start of the sequence 0x30
|
||||
derBytes.Add(derLength); //total length r lenth, type and r bytes
|
||||
|
||||
derBytes.Add(2); //tag for integer
|
||||
derBytes.Add(rbytesLength); //length of r
|
||||
derBytes.AddRange(rBytes);
|
||||
|
||||
derBytes.Add(2); //tag for integer
|
||||
derBytes.Add(sbytesLength); //length of s
|
||||
derBytes.AddRange(sBytes);
|
||||
return derBytes.ToArray();
|
||||
}
|
||||
|
||||
private RSACryptoServiceProvider GetRSAProviderFromPemFile(string pemfile, SecureString keyPassPharse = null)
|
||||
{
|
||||
const string pempubheader = "-----BEGIN PUBLIC KEY-----";
|
||||
const string pempubfooter = "-----END PUBLIC KEY-----";
|
||||
bool isPrivateKeyFile = true;
|
||||
byte[] pemkey = null;
|
||||
|
||||
if (!File.Exists(pemfile))
|
||||
{
|
||||
throw new Exception("private key file does not exist.");
|
||||
}
|
||||
string pemstr = File.ReadAllText(pemfile).Trim();
|
||||
|
||||
if (pemstr.StartsWith(pempubheader) && pemstr.EndsWith(pempubfooter))
|
||||
{
|
||||
isPrivateKeyFile = false;
|
||||
}
|
||||
|
||||
if (isPrivateKeyFile)
|
||||
{
|
||||
pemkey = ConvertPrivateKeyToBytes(pemstr, keyPassPharse);
|
||||
if (pemkey == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return DecodeRSAPrivateKey(pemkey);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private byte[] ConvertPrivateKeyToBytes(string instr, SecureString keyPassPharse = null)
|
||||
{
|
||||
const string pemprivheader = "-----BEGIN RSA PRIVATE KEY-----";
|
||||
const string pemprivfooter = "-----END RSA PRIVATE KEY-----";
|
||||
string pemstr = instr.Trim();
|
||||
byte[] binkey;
|
||||
|
||||
if (!pemstr.StartsWith(pemprivheader) || !pemstr.EndsWith(pemprivfooter))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(pemstr);
|
||||
sb.Replace(pemprivheader, "");
|
||||
sb.Replace(pemprivfooter, "");
|
||||
string pvkstr = sb.ToString().Trim();
|
||||
|
||||
try
|
||||
{ // if there are no PEM encryption info lines, this is an UNencrypted PEM private key
|
||||
binkey = Convert.FromBase64String(pvkstr);
|
||||
return binkey;
|
||||
}
|
||||
catch (System.FormatException)
|
||||
{
|
||||
StringReader str = new StringReader(pvkstr);
|
||||
|
||||
//-------- read PEM encryption info. lines and extract salt -----
|
||||
if (!str.ReadLine().StartsWith("Proc-Type: 4,ENCRYPTED"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string saltline = str.ReadLine();
|
||||
if (!saltline.StartsWith("DEK-Info: DES-EDE3-CBC,"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string saltstr = saltline.Substring(saltline.IndexOf(",") + 1).Trim();
|
||||
byte[] salt = new byte[saltstr.Length / 2];
|
||||
for (int i = 0; i < salt.Length; i++)
|
||||
salt[i] = Convert.ToByte(saltstr.Substring(i * 2, 2), 16);
|
||||
if (!(str.ReadLine() == ""))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
//------ remaining b64 data is encrypted RSA key ----
|
||||
string encryptedstr = str.ReadToEnd();
|
||||
|
||||
try
|
||||
{ //should have b64 encrypted RSA key now
|
||||
binkey = Convert.FromBase64String(encryptedstr);
|
||||
}
|
||||
catch (System.FormatException)
|
||||
{ //data is not in base64 fromat
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] deskey = GetEncryptedKey(salt, keyPassPharse, 1, 2); // count=1 (for OpenSSL implementation); 2 iterations to get at least 24 bytes
|
||||
if (deskey == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
//------ Decrypt the encrypted 3des-encrypted RSA private key ------
|
||||
byte[] rsakey = DecryptKey(binkey, deskey, salt); //OpenSSL uses salt value in PEM header also as 3DES IV
|
||||
return rsakey;
|
||||
}
|
||||
}
|
||||
|
||||
private RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
|
||||
{
|
||||
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
|
||||
|
||||
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
|
||||
MemoryStream mem = new MemoryStream(privkey);
|
||||
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
|
||||
byte bt = 0;
|
||||
ushort twobytes = 0;
|
||||
int elems = 0;
|
||||
try
|
||||
{
|
||||
twobytes = binr.ReadUInt16();
|
||||
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
|
||||
{
|
||||
binr.ReadByte(); //advance 1 byte
|
||||
}
|
||||
else if (twobytes == 0x8230)
|
||||
{
|
||||
binr.ReadInt16(); //advance 2 bytes
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
twobytes = binr.ReadUInt16();
|
||||
if (twobytes != 0x0102) //version number
|
||||
{
|
||||
return null;
|
||||
}
|
||||
bt = binr.ReadByte();
|
||||
if (bt != 0x00)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
//------ all private key components are Integer sequences ----
|
||||
elems = GetIntegerSize(binr);
|
||||
MODULUS = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
E = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
D = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
P = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
Q = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
DP = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
DQ = binr.ReadBytes(elems);
|
||||
|
||||
elems = GetIntegerSize(binr);
|
||||
IQ = binr.ReadBytes(elems);
|
||||
|
||||
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
|
||||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||||
RSAParameters RSAparams = new RSAParameters();
|
||||
RSAparams.Modulus = MODULUS;
|
||||
RSAparams.Exponent = E;
|
||||
RSAparams.D = D;
|
||||
RSAparams.P = P;
|
||||
RSAparams.Q = Q;
|
||||
RSAparams.DP = DP;
|
||||
RSAparams.DQ = DQ;
|
||||
RSAparams.InverseQ = IQ;
|
||||
RSA.ImportParameters(RSAparams);
|
||||
return RSA;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
binr.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private int GetIntegerSize(BinaryReader binr)
|
||||
{
|
||||
byte bt = 0;
|
||||
byte lowbyte = 0x00;
|
||||
byte highbyte = 0x00;
|
||||
int count = 0;
|
||||
bt = binr.ReadByte();
|
||||
if (bt != 0x02) //expect integer
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bt = binr.ReadByte();
|
||||
|
||||
if (bt == 0x81)
|
||||
{
|
||||
count = binr.ReadByte(); // data size in next byte
|
||||
}
|
||||
else if (bt == 0x82)
|
||||
{
|
||||
highbyte = binr.ReadByte(); // data size in next 2 bytes
|
||||
lowbyte = binr.ReadByte();
|
||||
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
|
||||
count = BitConverter.ToInt32(modint, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = bt; // we already have the data size
|
||||
}
|
||||
while (binr.ReadByte() == 0x00)
|
||||
{
|
||||
//remove high order zeros in data
|
||||
count -= 1;
|
||||
}
|
||||
binr.BaseStream.Seek(-1, SeekOrigin.Current);
|
||||
//last ReadByte wasn't a removed zero, so back up a byte
|
||||
return count;
|
||||
}
|
||||
|
||||
private byte[] GetEncryptedKey(byte[] salt, SecureString secpswd, int count, int miter)
|
||||
{
|
||||
IntPtr unmanagedPswd = IntPtr.Zero;
|
||||
int HASHLENGTH = 16; //MD5 bytes
|
||||
byte[] keymaterial = new byte[HASHLENGTH * miter]; //to store contatenated Mi hashed results
|
||||
|
||||
byte[] psbytes = new byte[secpswd.Length];
|
||||
unmanagedPswd = Marshal.SecureStringToGlobalAllocAnsi(secpswd);
|
||||
Marshal.Copy(unmanagedPswd, psbytes, 0, psbytes.Length);
|
||||
Marshal.ZeroFreeGlobalAllocAnsi(unmanagedPswd);
|
||||
|
||||
// --- contatenate salt and pswd bytes into fixed data array ---
|
||||
byte[] data00 = new byte[psbytes.Length + salt.Length];
|
||||
Array.Copy(psbytes, data00, psbytes.Length); //copy the pswd bytes
|
||||
Array.Copy(salt, 0, data00, psbytes.Length, salt.Length); //concatenate the salt bytes
|
||||
|
||||
// ---- do multi-hashing and contatenate results D1, D2 ... into keymaterial bytes ----
|
||||
MD5 md5 = new MD5CryptoServiceProvider();
|
||||
byte[] result = null;
|
||||
byte[] hashtarget = new byte[HASHLENGTH + data00.Length]; //fixed length initial hashtarget
|
||||
|
||||
for (int j = 0; j < miter; j++)
|
||||
{
|
||||
// ---- Now hash consecutively for count times ------
|
||||
if (j == 0)
|
||||
{
|
||||
result = data00; //initialize
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(result, hashtarget, result.Length);
|
||||
Array.Copy(data00, 0, hashtarget, result.Length, data00.Length);
|
||||
result = hashtarget;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
result = md5.ComputeHash(result);
|
||||
Array.Copy(result, 0, keymaterial, j * HASHLENGTH, result.Length); //contatenate to keymaterial
|
||||
}
|
||||
byte[] deskey = new byte[24];
|
||||
Array.Copy(keymaterial, deskey, deskey.Length);
|
||||
|
||||
Array.Clear(psbytes, 0, psbytes.Length);
|
||||
Array.Clear(data00, 0, data00.Length);
|
||||
Array.Clear(result, 0, result.Length);
|
||||
Array.Clear(hashtarget, 0, hashtarget.Length);
|
||||
Array.Clear(keymaterial, 0, keymaterial.Length);
|
||||
return deskey;
|
||||
}
|
||||
|
||||
private byte[] DecryptKey(byte[] cipherData, byte[] desKey, byte[] IV)
|
||||
{
|
||||
MemoryStream memst = new MemoryStream();
|
||||
TripleDES alg = TripleDES.Create();
|
||||
alg.Key = desKey;
|
||||
alg.IV = IV;
|
||||
try
|
||||
{
|
||||
CryptoStream cs = new CryptoStream(memst, alg.CreateDecryptor(), CryptoStreamMode.Write);
|
||||
cs.Write(cipherData, 0, cipherData.Length);
|
||||
cs.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
byte[] decryptedData = memst.ToArray();
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detect the key type from the pem file.
|
||||
/// </summary>
|
||||
/// <param name="keyFilePath">key file path in pem format</param>
|
||||
/// <returns></returns>
|
||||
private PrivateKeyType GetKeyType(string keyFilePath)
|
||||
{
|
||||
if (!File.Exists(keyFilePath))
|
||||
{
|
||||
throw new Exception("Key file path does not exist.");
|
||||
}
|
||||
|
||||
var ecPrivateKeyHeader = "BEGIN EC PRIVATE KEY";
|
||||
var ecPrivateKeyFooter = "END EC PRIVATE KEY";
|
||||
var rsaPrivateKeyHeader = "BEGIN RSA PRIVATE KEY";
|
||||
var rsaPrivateFooter = "END RSA PRIVATE KEY";
|
||||
//var pkcs8Header = "BEGIN PRIVATE KEY";
|
||||
//var pkcs8Footer = "END PRIVATE KEY";
|
||||
var keyType = PrivateKeyType.None;
|
||||
var key = File.ReadAllLines(keyFilePath);
|
||||
|
||||
if (key[0].ToString().Contains(rsaPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(rsaPrivateFooter))
|
||||
{
|
||||
keyType = PrivateKeyType.RSA;
|
||||
}
|
||||
else if (key[0].ToString().Contains(ecPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(ecPrivateKeyFooter))
|
||||
{
|
||||
keyType = PrivateKeyType.ECDSA;
|
||||
}
|
||||
else if (key[0].ToString().Contains(ecPrivateKeyHeader) &&
|
||||
key[key.Length - 1].ToString().Contains(ecPrivateKeyFooter))
|
||||
{
|
||||
|
||||
/* this type of key can hold many type different types of private key, but here due lack of pem header
|
||||
Considering this as EC key
|
||||
*/
|
||||
//TODO :- update the key based on oid
|
||||
keyType = PrivateKeyType.ECDSA;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Either the key is invalid or key is not supported");
|
||||
|
||||
}
|
||||
return keyType;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
29
modules/openapi-generator/src/main/resources/csharp-netcore-functions/IApiAccessor.mustache
vendored
Normal file
29
modules/openapi-generator/src/main/resources/csharp-netcore-functions/IApiAccessor.mustache
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents configuration aspects required to interact with the API endpoints.
|
||||
/// </summary>
|
||||
{{>visibility}} interface IApiAccessor
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration object
|
||||
/// </summary>
|
||||
/// <value>An instance of the Configuration</value>
|
||||
IReadableConfiguration Configuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base path of the API client.
|
||||
/// </summary>
|
||||
/// <value>The base path</value>
|
||||
string GetBasePath();
|
||||
|
||||
/// <summary>
|
||||
/// Provides a factory method hook for the creation of exceptions.
|
||||
/// </summary>
|
||||
ExceptionFactory ExceptionFactory { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Contract for Asynchronous RESTful API interactions.
|
||||
///
|
||||
/// This interface allows consumers to provide a custom API accessor client.
|
||||
/// </summary>
|
||||
public interface IAsynchronousClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes a non-blocking call to some <paramref name="path"/> using the GET http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
Task<ApiResponse<T>> GetAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Executes a non-blocking call to some <paramref name="path"/> using the POST http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
Task<ApiResponse<T>> PostAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Executes a non-blocking call to some <paramref name="path"/> using the PUT http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
Task<ApiResponse<T>> PutAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Executes a non-blocking call to some <paramref name="path"/> using the DELETE http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
Task<ApiResponse<T>> DeleteAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Executes a non-blocking call to some <paramref name="path"/> using the HEAD http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
Task<ApiResponse<T>> HeadAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Executes a non-blocking call to some <paramref name="path"/> using the OPTIONS http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
Task<ApiResponse<T>> OptionsAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Executes a non-blocking call to some <paramref name="path"/> using the PATCH http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>A task eventually representing the response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
Task<ApiResponse<T>> PatchAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a readable-only configuration contract.
|
||||
/// </summary>
|
||||
public interface IReadableConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the access token.
|
||||
/// </summary>
|
||||
/// <value>Access token.</value>
|
||||
string AccessToken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the API key.
|
||||
/// </summary>
|
||||
/// <value>API key.</value>
|
||||
IDictionary<string, string> ApiKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the API key prefix.
|
||||
/// </summary>
|
||||
/// <value>API key prefix.</value>
|
||||
IDictionary<string, string> ApiKeyPrefix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base path.
|
||||
/// </summary>
|
||||
/// <value>Base path.</value>
|
||||
string BasePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date time format.
|
||||
/// </summary>
|
||||
/// <value>Date time foramt.</value>
|
||||
string DateTimeFormat { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default header.
|
||||
/// </summary>
|
||||
/// <value>Default header.</value>
|
||||
[Obsolete("Use DefaultHeaders instead.")]
|
||||
IDictionary<string, string> DefaultHeader { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default headers.
|
||||
/// </summary>
|
||||
/// <value>Default headers.</value>
|
||||
IDictionary<string, string> DefaultHeaders { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the temp folder path.
|
||||
/// </summary>
|
||||
/// <value>Temp folder path.</value>
|
||||
string TempFolderPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTP connection timeout (in milliseconds)
|
||||
/// </summary>
|
||||
/// <value>HTTP connection timeout.</value>
|
||||
int Timeout { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the proxy.
|
||||
/// </summary>
|
||||
/// <value>Proxy.</value>
|
||||
WebProxy Proxy { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user agent.
|
||||
/// </summary>
|
||||
/// <value>User agent.</value>
|
||||
string UserAgent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the username.
|
||||
/// </summary>
|
||||
/// <value>Username.</value>
|
||||
string Username { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the password.
|
||||
/// </summary>
|
||||
/// <value>Password.</value>
|
||||
string Password { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the API key with prefix.
|
||||
/// </summary>
|
||||
/// <param name="apiKeyIdentifier">API key identifier (authentication scheme).</param>
|
||||
/// <returns>API key with prefix.</returns>
|
||||
string GetApiKeyWithPrefix(string apiKeyIdentifier);
|
||||
|
||||
/// <summary>
|
||||
/// Gets certificate collection to be sent with requests.
|
||||
/// </summary>
|
||||
/// <value>X509 Certificate collection.</value>
|
||||
X509CertificateCollection ClientCertificates { get; }
|
||||
{{#hasHttpSignatureMethods}}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HttpSigning configuration
|
||||
/// </summary>
|
||||
HttpSigningConfiguration HttpSigningConfiguration { get; }
|
||||
{{/hasHttpSignatureMethods}}
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Contract for Synchronous RESTful API interactions.
|
||||
///
|
||||
/// This interface allows consumers to provide a custom API accessor client.
|
||||
/// </summary>
|
||||
public interface ISynchronousClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes a blocking call to some <paramref name="path"/> using the GET http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
ApiResponse<T> Get<T>(string path, RequestOptions options, IReadableConfiguration configuration = null);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a blocking call to some <paramref name="path"/> using the POST http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
ApiResponse<T> Post<T>(string path, RequestOptions options, IReadableConfiguration configuration = null);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a blocking call to some <paramref name="path"/> using the PUT http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
ApiResponse<T> Put<T>(string path, RequestOptions options, IReadableConfiguration configuration = null);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a blocking call to some <paramref name="path"/> using the DELETE http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
ApiResponse<T> Delete<T>(string path, RequestOptions options, IReadableConfiguration configuration = null);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a blocking call to some <paramref name="path"/> using the HEAD http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
ApiResponse<T> Head<T>(string path, RequestOptions options, IReadableConfiguration configuration = null);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a blocking call to some <paramref name="path"/> using the OPTIONS http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
ApiResponse<T> Options<T>(string path, RequestOptions options, IReadableConfiguration configuration = null);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a blocking call to some <paramref name="path"/> using the PATCH http verb.
|
||||
/// </summary>
|
||||
/// <param name="path">The relative path to invoke.</param>
|
||||
/// <param name="options">The request parameters to pass along to the client.</param>
|
||||
/// <param name="configuration">Per-request configurable settings.</param>
|
||||
/// <typeparam name="T">The return type.</typeparam>
|
||||
/// <returns>The response data, decorated with <see cref="ApiResponse{T}"/></returns>
|
||||
ApiResponse<T> Patch<T>(string path, RequestOptions options, IReadableConfiguration configuration = null);
|
||||
}
|
||||
}
|
125
modules/openapi-generator/src/main/resources/csharp-netcore-functions/JsonSubTypesTests.mustache
vendored
Normal file
125
modules/openapi-generator/src/main/resources/csharp-netcore-functions/JsonSubTypesTests.mustache
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JsonSubTypes;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
|
||||
using {{packageName}}.{{apiPackage}};
|
||||
using {{packageName}}.{{modelPackage}};
|
||||
using {{packageName}}.Client;
|
||||
|
||||
namespace {{packageName}}.Test.Client
|
||||
{
|
||||
public class JsonSubTypesTests
|
||||
{
|
||||
[Test]
|
||||
public void TestSimpleJsonSubTypesExample()
|
||||
{
|
||||
var annimal =
|
||||
JsonConvert.DeserializeObject<IAnimal>("{\"Kind\":\"Dog\",\"Breed\":\"Jack Russell Terrier\"}");
|
||||
Assert.AreEqual("Jack Russell Terrier", (annimal as Dog)?.Breed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeObjectWithCustomMapping()
|
||||
{
|
||||
var annimal =
|
||||
JsonConvert.DeserializeObject<Animal2>("{\"Sound\":\"Bark\",\"Breed\":\"Jack Russell Terrier\"}");
|
||||
Assert.AreEqual("Jack Russell Terrier", (annimal as Dog2)?.Breed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeObjectMappingByPropertyPresence()
|
||||
{
|
||||
string json =
|
||||
"[{\"Department\":\"Department1\",\"JobTitle\":\"JobTitle1\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}," +
|
||||
"{\"Department\":\"Department1\",\"JobTitle\":\"JobTitle1\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}," +
|
||||
"{\"Skill\":\"Painter\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}]";
|
||||
|
||||
|
||||
var persons = JsonConvert.DeserializeObject<ICollection<Person>>(json);
|
||||
Assert.AreEqual("Painter", (persons.Last() as Artist)?.Skill);
|
||||
}
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(JsonSubtypes), "Kind")]
|
||||
public interface IAnimal
|
||||
{
|
||||
string Kind { get; }
|
||||
}
|
||||
|
||||
public class Dog : IAnimal
|
||||
{
|
||||
public Dog()
|
||||
{
|
||||
Kind = "Dog";
|
||||
}
|
||||
|
||||
public string Kind { get; }
|
||||
public string Breed { get; set; }
|
||||
}
|
||||
|
||||
class Cat : IAnimal
|
||||
{
|
||||
public Cat()
|
||||
{
|
||||
Kind = "Cat";
|
||||
}
|
||||
|
||||
public string Kind { get; }
|
||||
bool Declawed { get; set; }
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(JsonSubtypes), "Sound")]
|
||||
[JsonSubtypes.KnownSubType(typeof(Dog2), "Bark")]
|
||||
[JsonSubtypes.KnownSubType(typeof(Cat2), "Meow")]
|
||||
public class Animal2
|
||||
{
|
||||
public virtual string Sound { get; }
|
||||
public string Color { get; set; }
|
||||
}
|
||||
|
||||
public class Dog2 : Animal2
|
||||
{
|
||||
public Dog2()
|
||||
{
|
||||
Sound = "Bark";
|
||||
}
|
||||
|
||||
public override string Sound { get; }
|
||||
public string Breed { get; set; }
|
||||
}
|
||||
|
||||
public class Cat2 : Animal2
|
||||
{
|
||||
public Cat2()
|
||||
{
|
||||
Sound = "Meow";
|
||||
}
|
||||
|
||||
public override string Sound { get; }
|
||||
public bool Declawed { get; set; }
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(JsonSubtypes))]
|
||||
[JsonSubtypes.KnownSubTypeWithProperty(typeof(Employee), "JobTitle")]
|
||||
[JsonSubtypes.KnownSubTypeWithProperty(typeof(Artist), "Skill")]
|
||||
public class Person
|
||||
{
|
||||
public string FirstName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
}
|
||||
|
||||
public class Employee : Person
|
||||
{
|
||||
public string Department { get; set; }
|
||||
public string JobTitle { get; set; }
|
||||
}
|
||||
|
||||
public class Artist : Person
|
||||
{
|
||||
public string Skill { get; set; }
|
||||
}
|
||||
}
|
287
modules/openapi-generator/src/main/resources/csharp-netcore-functions/Multimap.mustache
vendored
Normal file
287
modules/openapi-generator/src/main/resources/csharp-netcore-functions/Multimap.mustache
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// A dictionary in which one key has many associated values.
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">The type of the key</typeparam>
|
||||
/// <typeparam name="TValue">The type of the value associated with the key.</typeparam>
|
||||
public class Multimap<TKey, TValue> : IDictionary<TKey, IList<TValue>>
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
private readonly Dictionary<TKey, IList<TValue>> _dictionary;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Empty Constructor.
|
||||
/// </summary>
|
||||
public Multimap()
|
||||
{
|
||||
_dictionary = new Dictionary<TKey, IList<TValue>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with comparer.
|
||||
/// </summary>
|
||||
/// <param name="comparer"></param>
|
||||
public Multimap(IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
_dictionary = new Dictionary<TKey, IList<TValue>>(comparer);
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
#region Enumerators
|
||||
|
||||
/// <summary>
|
||||
/// To get the enumerator.
|
||||
/// </summary>
|
||||
/// <returns>Enumerator</returns>
|
||||
public IEnumerator<KeyValuePair<TKey, IList<TValue>>> GetEnumerator()
|
||||
{
|
||||
return _dictionary.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To get the enumerator.
|
||||
/// </summary>
|
||||
/// <returns>Enumerator</returns>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return _dictionary.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion Enumerators
|
||||
|
||||
#region Public Members
|
||||
/// <summary>
|
||||
/// Add values to Multimap
|
||||
/// </summary>
|
||||
/// <param name="item">Key value pair</param>
|
||||
public void Add(KeyValuePair<TKey, IList<TValue>> item)
|
||||
{
|
||||
if (!TryAdd(item.Key, item.Value))
|
||||
throw new InvalidOperationException("Could not add values to Multimap.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Multimap to Multimap
|
||||
/// </summary>
|
||||
/// <param name="multimap">Multimap</param>
|
||||
public void Add(Multimap<TKey, TValue> multimap)
|
||||
{
|
||||
foreach (var item in multimap)
|
||||
{
|
||||
if (!TryAdd(item.Key, item.Value))
|
||||
throw new InvalidOperationException("Could not add values to Multimap.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear Multimap
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_dictionary.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether Multimap contains the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">Key value pair</param>
|
||||
/// <exception cref="NotImplementedException">Method needs to be implemented</exception>
|
||||
/// <returns>true if the Multimap contains the item; otherwise, false.</returns>
|
||||
public bool Contains(KeyValuePair<TKey, IList<TValue>> item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy items of the Multimap to an array,
|
||||
/// starting at a particular array index.
|
||||
/// </summary>
|
||||
/// <param name="array">The array that is the destination of the items copied
|
||||
/// from Multimap. The array must have zero-based indexing.</param>
|
||||
/// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
|
||||
/// <exception cref="NotImplementedException">Method needs to be implemented</exception>
|
||||
public void CopyTo(KeyValuePair<TKey, IList<TValue>>[] array, int arrayIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified item from the Multimap.
|
||||
/// </summary>
|
||||
/// <param name="item">Key value pair</param>
|
||||
/// <returns>true if the item is successfully removed; otherwise, false.</returns>
|
||||
/// <exception cref="NotImplementedException">Method needs to be implemented</exception>
|
||||
public bool Remove(KeyValuePair<TKey, IList<TValue>> item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of items contained in the Multimap.
|
||||
/// </summary>
|
||||
public int Count => _dictionary.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the Multimap is read-only.
|
||||
/// </summary>
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item with the provided key and value to the Multimap.
|
||||
/// </summary>
|
||||
/// <param name="key">The object to use as the key of the item to add.</param>
|
||||
/// <param name="value">The object to use as the value of the item to add.</param>
|
||||
/// <exception cref="InvalidOperationException">Thrown when couldn't add the value to Multimap.</exception>
|
||||
public void Add(TKey key, IList<TValue> value)
|
||||
{
|
||||
if (value != null && value.Count > 0)
|
||||
{
|
||||
if (_dictionary.TryGetValue(key, out var list))
|
||||
{
|
||||
foreach (var k in value) list.Add(k);
|
||||
}
|
||||
else
|
||||
{
|
||||
list = new List<TValue>(value);
|
||||
if (!TryAdd(key, list))
|
||||
throw new InvalidOperationException("Could not add values to Multimap.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the Multimap contains an item with the specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to locate in the Multimap.</param>
|
||||
/// <returns>true if the Multimap contains an item with
|
||||
/// the key; otherwise, false.</returns>
|
||||
public bool ContainsKey(TKey key)
|
||||
{
|
||||
return _dictionary.ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes item with the specified key from the Multimap.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to locate in the Multimap.</param>
|
||||
/// <returns>true if the item is successfully removed; otherwise, false.</returns>
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
return TryRemove(key, out var _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value associated with the specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key whose value to get.</param>
|
||||
/// <param name="value">When this method returns, the value associated with the specified key, if the
|
||||
/// key is found; otherwise, the default value for the type of the value parameter.
|
||||
/// This parameter is passed uninitialized.</param>
|
||||
/// <returns> true if the object that implements Multimap contains
|
||||
/// an item with the specified key; otherwise, false.</returns>
|
||||
public bool TryGetValue(TKey key, out IList<TValue> value)
|
||||
{
|
||||
return _dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item with the specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the item to get or set.</param>
|
||||
/// <returns>The value of the specified key.</returns>
|
||||
public IList<TValue> this[TKey key]
|
||||
{
|
||||
get => _dictionary[key];
|
||||
set => _dictionary[key] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Collections.Generic.ICollection containing the keys of the Multimap.
|
||||
/// </summary>
|
||||
public ICollection<TKey> Keys => _dictionary.Keys;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Collections.Generic.ICollection containing the values of the Multimap.
|
||||
/// </summary>
|
||||
public ICollection<IList<TValue>> Values => _dictionary.Values;
|
||||
|
||||
/// <summary>
|
||||
/// Copy the items of the Multimap to an System.Array,
|
||||
/// starting at a particular System.Array index.
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional System.Array that is the destination of the items copied
|
||||
/// from Multimap. The System.Array must have zero-based indexing.</param>
|
||||
/// <param name="index">The zero-based index in array at which copying begins.</param>
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
((ICollection)_dictionary).CopyTo(array, index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item with the provided key and value to the Multimap.
|
||||
/// </summary>
|
||||
/// <param name="key">The object to use as the key of the item to add.</param>
|
||||
/// <param name="value">The object to use as the value of the item to add.</param>
|
||||
/// <exception cref="InvalidOperationException">Thrown when couldn't add value to Multimap.</exception>
|
||||
public void Add(TKey key, TValue value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
if (_dictionary.TryGetValue(key, out var list))
|
||||
{
|
||||
list.Add(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
list = new List<TValue> { value };
|
||||
if (!TryAdd(key, list))
|
||||
throw new InvalidOperationException("Could not add value to Multimap.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Members
|
||||
|
||||
#region Private Members
|
||||
|
||||
/**
|
||||
* Helper method to encapsulate generator differences between dictionary types.
|
||||
*/
|
||||
private bool TryRemove(TKey key, out IList<TValue> value)
|
||||
{
|
||||
_dictionary.TryGetValue(key, out value);
|
||||
return _dictionary.Remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to encapsulate generator differences between dictionary types.
|
||||
*/
|
||||
private bool TryAdd(TKey key, IList<TValue> value)
|
||||
{
|
||||
try
|
||||
{
|
||||
_dictionary.Add(key, value);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endregion Private Members
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
{{>partial_header}}
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Formatter for 'date' openapi formats ss defined by full-date - RFC3339
|
||||
/// see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#data-types
|
||||
/// </summary>
|
||||
public class OpenAPIDateConverter : IsoDateTimeConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenAPIDateConverter" /> class.
|
||||
/// </summary>
|
||||
public OpenAPIDateConverter()
|
||||
{
|
||||
// full-date = date-fullyear "-" date-month "-" date-mday
|
||||
DateTimeFormat = "yyyy-MM-dd";
|
||||
}
|
||||
}
|
||||
}
|
270
modules/openapi-generator/src/main/resources/csharp-netcore-functions/README.mustache
vendored
Normal file
270
modules/openapi-generator/src/main/resources/csharp-netcore-functions/README.mustache
vendored
Normal file
@ -0,0 +1,270 @@
|
||||
# {{packageName}} - the C# library for the {{appName}}
|
||||
|
||||
{{#appDescriptionWithNewLines}}
|
||||
{{{appDescriptionWithNewLines}}}
|
||||
{{/appDescriptionWithNewLines}}
|
||||
|
||||
This C# SDK is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
||||
|
||||
- API version: {{appVersion}}
|
||||
- SDK version: {{packageVersion}}
|
||||
{{^hideGenerationTimestamp}}
|
||||
- Build date: {{generatedDate}}
|
||||
{{/hideGenerationTimestamp}}
|
||||
- Build package: {{generatorClass}}
|
||||
{{#infoUrl}}
|
||||
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
|
||||
{{/infoUrl}}
|
||||
|
||||
<a name="frameworks-supported"></a>
|
||||
## Frameworks supported
|
||||
{{#netStandard}}
|
||||
- .NET Core >=1.0
|
||||
- .NET Framework >=4.6
|
||||
- Mono/Xamarin >=vNext
|
||||
{{/netStandard}}
|
||||
|
||||
<a name="dependencies"></a>
|
||||
## Dependencies
|
||||
|
||||
{{#useRestSharp}}
|
||||
- [RestSharp](https://www.nuget.org/packages/RestSharp) - 106.11.7 or later
|
||||
{{/useRestSharp}}
|
||||
- [Json.NET](https://www.nuget.org/packages/Newtonsoft.Json/) - 12.0.3 or later
|
||||
- [JsonSubTypes](https://www.nuget.org/packages/JsonSubTypes/) - 1.8.0 or later
|
||||
{{#useCompareNetObjects}}
|
||||
- [CompareNETObjects](https://www.nuget.org/packages/CompareNETObjects) - 4.61.0 or later
|
||||
{{/useCompareNetObjects}}
|
||||
{{#validatable}}
|
||||
- [System.ComponentModel.Annotations](https://www.nuget.org/packages/System.ComponentModel.Annotations) - 5.0.0 or later
|
||||
{{/validatable}}
|
||||
|
||||
The DLLs included in the package may not be the latest version. We recommend using [NuGet](https://docs.nuget.org/consume/installing-nuget) to obtain the latest version of the packages:
|
||||
```
|
||||
{{#useRestSharp}}
|
||||
Install-Package RestSharp
|
||||
{{/useRestSharp}}
|
||||
Install-Package Newtonsoft.Json
|
||||
Install-Package JsonSubTypes
|
||||
{{#validatable}}
|
||||
Install-Package System.ComponentModel.Annotations
|
||||
{{/validatable}}
|
||||
{{#useCompareNetObjects}}
|
||||
Install-Package CompareNETObjects
|
||||
{{/useCompareNetObjects}}
|
||||
```
|
||||
{{#useRestSharp}}
|
||||
|
||||
NOTE: RestSharp versions greater than 105.1.0 have a bug which causes file uploads to fail. See [RestSharp#742](https://github.com/restsharp/RestSharp/issues/742).
|
||||
NOTE: RestSharp for .Net Core creates a new socket for each api call, which can lead to a socket exhaustion problem. See [RestSharp#1406](https://github.com/restsharp/RestSharp/issues/1406).
|
||||
|
||||
{{/useRestSharp}}
|
||||
<a name="installation"></a>
|
||||
## Installation
|
||||
{{#netStandard}}
|
||||
Generate the DLL using your preferred tool (e.g. `dotnet build`)
|
||||
{{/netStandard}}
|
||||
{{^netStandard}}
|
||||
Run the following command to generate the DLL
|
||||
- [Mac/Linux] `/bin/sh build.sh`
|
||||
- [Windows] `build.bat`
|
||||
{{/netStandard}}
|
||||
|
||||
Then include the DLL (under the `bin` folder) in the C# project, and use the namespaces:
|
||||
```csharp
|
||||
using {{packageName}}.{{apiPackage}};
|
||||
using {{packageName}}.Client;
|
||||
using {{packageName}}.{{modelPackage}};
|
||||
```
|
||||
{{^netStandard}}
|
||||
<a name="packaging"></a>
|
||||
## Packaging
|
||||
|
||||
A `.nuspec` is included with the project. You can follow the Nuget quickstart to [create](https://docs.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package#create-the-package) and [publish](https://docs.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package#publish-the-package) packages.
|
||||
|
||||
This `.nuspec` uses placeholders from the `.csproj`, so build the `.csproj` directly:
|
||||
|
||||
```
|
||||
nuget pack -Build -OutputDirectory out {{packageName}}.csproj
|
||||
```
|
||||
|
||||
Then, publish to a [local feed](https://docs.microsoft.com/en-us/nuget/hosting-packages/local-feeds) or [other host](https://docs.microsoft.com/en-us/nuget/hosting-packages/overview) and consume the new package via Nuget as usual.
|
||||
|
||||
{{/netStandard}}
|
||||
<a name="usage"></a>
|
||||
## Usage
|
||||
|
||||
To use the API client with a HTTP proxy, setup a `System.Net.WebProxy`
|
||||
```csharp
|
||||
Configuration c = new Configuration();
|
||||
System.Net.WebProxy webProxy = new System.Net.WebProxy("http://myProxyUrl:80/");
|
||||
webProxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
|
||||
c.Proxy = webProxy;
|
||||
```
|
||||
{{#useHttpClient}}
|
||||
|
||||
### Connections
|
||||
Each ApiClass (properly the ApiClient inside it) will create an istance of HttpClient. It will use that for the entire lifecycle and dispose it when called the Dispose method.
|
||||
|
||||
To better manager the connections it's a common practice to reuse the HttpClient and HttpClientHander (see [here](https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests#issues-with-the-original-httpclient-class-available-in-net) for details). To use your own HttpClient instance just pass it to the ApiClass constructor.
|
||||
|
||||
```csharp
|
||||
HttpClientHandler yourHandler = new HttpClientHandler();
|
||||
HttpClient yourHttpClient = new HttpClient(yourHandler);
|
||||
var api = new YourApiClass(yourHttpClient, yourHandler);
|
||||
```
|
||||
|
||||
If you want to use an HttpClient and don't have access to the handler, for example in a DI context in Asp.net Core when using IHttpClientFactory.
|
||||
|
||||
```csharp
|
||||
HttpClient yourHttpClient = new HttpClient();
|
||||
var api = new YourApiClass(yourHttpClient);
|
||||
```
|
||||
You'll loose some configuration settings, the features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings. You need to either manually handle those in your setup of the HttpClient or they won't be available.
|
||||
|
||||
Here an example of DI setup in a sample web project:
|
||||
|
||||
```csharp
|
||||
services.AddHttpClient<YourApiClass>(httpClient =>
|
||||
new PetApi(httpClient));
|
||||
```
|
||||
|
||||
{{/useHttpClient}}
|
||||
|
||||
<a name="getting-started"></a>
|
||||
## Getting Started
|
||||
|
||||
```csharp
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
{{#useHttpClient}}
|
||||
using System.Net.Http;
|
||||
{{/useHttpClient}}
|
||||
using {{packageName}}.{{apiPackage}};
|
||||
using {{packageName}}.Client;
|
||||
using {{packageName}}.{{modelPackage}};
|
||||
|
||||
namespace Example
|
||||
{
|
||||
public class {{operationId}}Example
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}}
|
||||
Configuration config = new Configuration();
|
||||
config.BasePath = "{{{basePath}}}";
|
||||
{{#hasAuthMethods}}
|
||||
{{#authMethods}}
|
||||
{{#isBasicBasic}}
|
||||
// Configure HTTP basic authorization: {{{name}}}
|
||||
config.Username = "YOUR_USERNAME";
|
||||
config.Password = "YOUR_PASSWORD";
|
||||
{{/isBasicBasic}}
|
||||
{{#isBasicBearer}}
|
||||
// Configure Bearer token for authorization: {{{name}}}
|
||||
config.AccessToken = "YOUR_BEARER_TOKEN";
|
||||
{{/isBasicBearer}}
|
||||
{{#isApiKey}}
|
||||
// Configure API key authorization: {{{name}}}
|
||||
config.ApiKey.Add("{{{keyParamName}}}", "YOUR_API_KEY");
|
||||
// Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||
// config.ApiKeyPrefix.Add("{{{keyParamName}}}", "Bearer");
|
||||
{{/isApiKey}}
|
||||
{{#isOAuth}}
|
||||
// Configure OAuth2 access token for authorization: {{{name}}}
|
||||
config.AccessToken = "YOUR_ACCESS_TOKEN";
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
|
||||
{{/hasAuthMethods}}
|
||||
{{#useHttpClient}}
|
||||
// create instances of HttpClient, HttpClientHandler to be reused later with different Api classes
|
||||
HttpClient httpClient = new HttpClient();
|
||||
HttpClientHandler httpClientHandler = new HttpClientHandler();
|
||||
var apiInstance = new {{classname}}(httpClient, config, httpClientHandler);
|
||||
{{/useHttpClient}}
|
||||
{{^useHttpClient}}
|
||||
var apiInstance = new {{classname}}(config);
|
||||
{{/useHttpClient}}
|
||||
{{#allParams}}
|
||||
{{#isPrimitiveType}}
|
||||
var {{paramName}} = {{{example}}}; // {{{dataType}}} | {{{description}}}{{^required}} (optional) {{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
var {{paramName}} = new {{{dataType}}}(); // {{{dataType}}} | {{{description}}}{{^required}} (optional) {{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/allParams}}
|
||||
|
||||
try
|
||||
{
|
||||
{{#summary}}
|
||||
// {{{.}}}
|
||||
{{/summary}}
|
||||
{{#returnType}}{{{returnType}}} result = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});{{#returnType}}
|
||||
Debug.WriteLine(result);{{/returnType}}
|
||||
}
|
||||
catch (ApiException e)
|
||||
{
|
||||
Debug.Print("Exception when calling {{classname}}.{{operationId}}: " + e.Message );
|
||||
Debug.Print("Status Code: "+ e.ErrorCode);
|
||||
Debug.Print(e.StackTrace);
|
||||
}
|
||||
{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<a name="documentation-for-api-endpoints"></a>
|
||||
## Documentation for API Endpoints
|
||||
|
||||
All URIs are relative to *{{{basePath}}}*
|
||||
|
||||
Class | Method | HTTP request | Description
|
||||
------------ | ------------- | ------------- | -------------
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{{summary}}}{{/summary}}
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
<a name="documentation-for-models"></a>
|
||||
## Documentation for Models
|
||||
|
||||
{{#modelPackage}}
|
||||
{{#models}}{{#model}} - [{{{modelPackage}}}.{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
|
||||
{{/model}}{{/models}}
|
||||
{{/modelPackage}}
|
||||
{{^modelPackage}}
|
||||
No model defined in this package
|
||||
{{/modelPackage}}
|
||||
|
||||
<a name="documentation-for-authorization"></a>
|
||||
## Documentation for Authorization
|
||||
|
||||
{{^authMethods}}
|
||||
All endpoints do not require authorization.
|
||||
{{/authMethods}}
|
||||
{{#authMethods}}
|
||||
{{#last}}
|
||||
Authentication schemes defined for the API:
|
||||
{{/last}}
|
||||
{{/authMethods}}
|
||||
{{#authMethods}}
|
||||
<a name="{{name}}"></a>
|
||||
### {{name}}
|
||||
|
||||
{{#isApiKey}}- **Type**: API key
|
||||
- **API key parameter name**: {{keyParamName}}
|
||||
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
|
||||
{{/isApiKey}}
|
||||
{{#isBasicBasic}}- **Type**: HTTP basic authentication
|
||||
{{/isBasicBasic}}
|
||||
{{#isBasicBearer}}- **Type**: Bearer Authentication
|
||||
{{/isBasicBearer}}
|
||||
{{#isOAuth}}- **Type**: OAuth
|
||||
- **Flow**: {{flow}}
|
||||
- **Authorization URL**: {{authorizationUrl}}
|
||||
- **Scopes**: {{^scopes}}N/A{{/scopes}}
|
||||
{{#scopes}} - {{scope}}: {{description}}
|
||||
{{/scopes}}
|
||||
{{/isOAuth}}
|
||||
|
||||
{{/authMethods}}
|
137
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ReadOnlyDictionary.mustache
vendored
Normal file
137
modules/openapi-generator/src/main/resources/csharp-netcore-functions/ReadOnlyDictionary.mustache
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
{{>partial_header}}
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
public class ReadOnlyDictionary<T, K> : IDictionary<T, K>
|
||||
{
|
||||
private IDictionary<T, K> _dictionaryImplementation;
|
||||
public IEnumerator<KeyValuePair<T, K>> GetEnumerator()
|
||||
{
|
||||
return _dictionaryImplementation.GetEnumerator();
|
||||
}
|
||||
|
||||
public ReadOnlyDictionary()
|
||||
{
|
||||
_dictionaryImplementation = new Dictionary<T, K>();
|
||||
}
|
||||
|
||||
public ReadOnlyDictionary(IDictionary<T, K> dictionaryImplementation)
|
||||
{
|
||||
if (dictionaryImplementation == null) throw new ArgumentNullException("dictionaryImplementation");
|
||||
_dictionaryImplementation = dictionaryImplementation;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable) _dictionaryImplementation).GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<T, K> item)
|
||||
{
|
||||
throw new ReadonlyOperationException("This instance is readonly.");
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
throw new ReadonlyOperationException("This instance is readonly.");
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<T, K> item)
|
||||
{
|
||||
return _dictionaryImplementation.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<T, K>[] array, int arrayIndex)
|
||||
{
|
||||
_dictionaryImplementation.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<T, K> item)
|
||||
{
|
||||
throw new ReadonlyOperationException("This instance is readonly.");
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _dictionaryImplementation.Count; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public void Add(T key, K value)
|
||||
{
|
||||
throw new ReadonlyOperationException("This instance is readonly.");
|
||||
}
|
||||
|
||||
public bool ContainsKey(T key)
|
||||
{
|
||||
return _dictionaryImplementation.ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool Remove(T key)
|
||||
{
|
||||
throw new ReadonlyOperationException("This instance is readonly.");
|
||||
}
|
||||
|
||||
public bool TryGetValue(T key, out K value)
|
||||
{
|
||||
return _dictionaryImplementation.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public K this[T key]
|
||||
{
|
||||
get { return _dictionaryImplementation[key]; }
|
||||
set
|
||||
{
|
||||
throw new ReadonlyOperationException("This instance is readonly.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<T> Keys
|
||||
{
|
||||
get { return _dictionaryImplementation.Keys; }
|
||||
}
|
||||
|
||||
public ICollection<K> Values
|
||||
{
|
||||
get { return _dictionaryImplementation.Values; }
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ReadonlyOperationException : Exception
|
||||
{
|
||||
//
|
||||
// For guidelines regarding the creation of new exception types, see
|
||||
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp
|
||||
// and
|
||||
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp
|
||||
//
|
||||
|
||||
public ReadonlyOperationException()
|
||||
{
|
||||
}
|
||||
|
||||
public ReadonlyOperationException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public ReadonlyOperationException(string message, Exception inner) : base(message, inner)
|
||||
{
|
||||
}
|
||||
|
||||
protected ReadonlyOperationException(
|
||||
SerializationInfo info,
|
||||
StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
66
modules/openapi-generator/src/main/resources/csharp-netcore-functions/RequestOptions.mustache
vendored
Normal file
66
modules/openapi-generator/src/main/resources/csharp-netcore-functions/RequestOptions.mustache
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// A container for generalized request inputs. This type allows consumers to extend the request functionality
|
||||
/// by abstracting away from the default (built-in) request framework (e.g. RestSharp).
|
||||
/// </summary>
|
||||
public class RequestOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters to be bound to path parts of the Request's URL
|
||||
/// </summary>
|
||||
public Dictionary<string, string> PathParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Query parameters to be applied to the request.
|
||||
/// Keys may have 1 or more values associated.
|
||||
/// </summary>
|
||||
public Multimap<string, string> QueryParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Header parameters to be applied to to the request.
|
||||
/// Keys may have 1 or more values associated.
|
||||
/// </summary>
|
||||
public Multimap<string, string> HeaderParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Form parameters to be sent along with the request.
|
||||
/// </summary>
|
||||
public Dictionary<string, string> FormParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File parameters to be sent along with the request.
|
||||
/// </summary>
|
||||
public Dictionary<string, Stream> FileParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cookies to be sent along with the request.
|
||||
/// </summary>
|
||||
public List<Cookie> Cookies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Any data associated with a request body.
|
||||
/// </summary>
|
||||
public Object Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of <see cref="RequestOptions"/>
|
||||
/// </summary>
|
||||
public RequestOptions()
|
||||
{
|
||||
PathParameters = new Dictionary<string, string>();
|
||||
QueryParameters = new Multimap<string, string>();
|
||||
HeaderParameters = new Multimap<string, string>();
|
||||
FormParameters = new Dictionary<string, string>();
|
||||
FileParameters = new Dictionary<string, Stream>();
|
||||
Cookies = new List<Cookie>();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
using Polly;
|
||||
{{#useRestSharp}}
|
||||
using RestSharp;
|
||||
{{/useRestSharp}}
|
||||
{{#useHttpClient}}
|
||||
using System.Net.Http;
|
||||
{{/useHttpClient}}
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration class to set the polly retry policies to be applied to the requests.
|
||||
/// </summary>
|
||||
public class RetryConfiguration
|
||||
{
|
||||
{{#useRestSharp}}
|
||||
/// <summary>
|
||||
/// Retry policy
|
||||
/// </summary>
|
||||
public static Policy<IRestResponse> RetryPolicy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Async retry policy
|
||||
/// </summary>
|
||||
public static AsyncPolicy<IRestResponse> AsyncRetryPolicy { get; set; }
|
||||
{{/useRestSharp}}
|
||||
{{#useHttpClient}}
|
||||
/// <summary>
|
||||
/// Retry policy
|
||||
/// </summary>
|
||||
public static Policy<HttpResponseMessage> RetryPolicy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Async retry policy
|
||||
/// </summary>
|
||||
public static AsyncPolicy<HttpResponseMessage> AsyncRetryPolicy { get; set; }
|
||||
{{/useHttpClient}}
|
||||
}
|
||||
}
|
27
modules/openapi-generator/src/main/resources/csharp-netcore-functions/Solution.mustache
vendored
Normal file
27
modules/openapi-generator/src/main/resources/csharp-netcore-functions/Solution.mustache
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio {{^netStandard}}2012{{/netStandard}}{{#netStandard}}14{{/netStandard}}
|
||||
VisualStudioVersion = {{^netStandard}}12.0.0.0{{/netStandard}}{{#netStandard}}14.0.25420.1{{/netStandard}}
|
||||
MinimumVisualStudioVersion = {{^netStandard}}10.0.0.1{{/netStandard}}{{#netStandard}}10.0.40219.1{{/netStandard}}
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "{{packageName}}", "src\{{packageName}}\{{packageName}}.csproj", "{{packageGuid}}"
|
||||
EndProject
|
||||
{{^excludeTests}}Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "{{testPackageName}}", "src\{{testPackageName}}\{{testPackageName}}.csproj", "{19F1DEBC-DE5E-4517-8062-F000CD499087}"
|
||||
EndProject
|
||||
{{/excludeTests}}Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{{packageGuid}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{{packageGuid}}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{{packageGuid}}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{{packageGuid}}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
36
modules/openapi-generator/src/main/resources/csharp-netcore-functions/TestProject.mustache
vendored
Normal file
36
modules/openapi-generator/src/main/resources/csharp-netcore-functions/TestProject.mustache
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
{{#appName}}
|
||||
{{{appName}}}
|
||||
|
||||
{{/appName}}
|
||||
{{#appDescription}}
|
||||
{{{appDescription}}}
|
||||
|
||||
{{/appDescription}}
|
||||
{{#version}}The version of the OpenAPI document: {{{version}}}{{/version}}
|
||||
{{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
|
||||
-->
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>{{testPackageName}}</RootNamespace>
|
||||
<AssemblyName>{{testPackageName}}</AssemblyName>
|
||||
<TargetFramework{{#multiTarget}}s{{/multiTarget}}>{{testTargetFramework}}</TargetFramework{{#multiTarget}}s{{/multiTarget}}>
|
||||
<IsPackable>false</IsPackable>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.2" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\{{packageName}}\{{packageName}}.csproj">
|
||||
<Project>{{packageGuid}}</Project>
|
||||
<Name>{{packageName}}</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -0,0 +1,44 @@
|
||||
{{>partial_header}}
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// A URI builder
|
||||
/// </summary>
|
||||
class WebRequestPathBuilder
|
||||
{
|
||||
private string _baseUrl;
|
||||
private string _path;
|
||||
private string _query = "?";
|
||||
public WebRequestPathBuilder(string baseUrl, string path)
|
||||
{
|
||||
_baseUrl = baseUrl;
|
||||
_path = path;
|
||||
}
|
||||
|
||||
public void AddPathParameters(Dictionary<string, string> parameters)
|
||||
{
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
_path = _path.Replace("{" + parameter.Key + "}", parameter.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddQueryParameters(Multimap<string, string> parameters)
|
||||
{
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
foreach (var value in parameter.Value)
|
||||
{
|
||||
_query = _query + parameter.Key + "=" + value + "&";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFullUri()
|
||||
{
|
||||
return _baseUrl + _path + _query.Substring(0, _query.Length - 1);
|
||||
}
|
||||
}
|
||||
}
|
626
modules/openapi-generator/src/main/resources/csharp-netcore-functions/api.mustache
vendored
Normal file
626
modules/openapi-generator/src/main/resources/csharp-netcore-functions/api.mustache
vendored
Normal file
@ -0,0 +1,626 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Mime;
|
||||
using {{packageName}}.Client;
|
||||
{{#hasImport}}using {{packageName}}.{{modelPackage}};
|
||||
{{/hasImport}}
|
||||
|
||||
namespace {{packageName}}.{{apiPackage}}
|
||||
{
|
||||
{{#operations}}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of functions to interact with the API endpoints
|
||||
/// </summary>
|
||||
{{>visibility}} interface {{interfacePrefix}}{{classname}}Sync : IApiAccessor
|
||||
{
|
||||
#region Synchronous Operations
|
||||
{{#operation}}
|
||||
/// <summary>
|
||||
/// {{summary}}
|
||||
/// </summary>
|
||||
{{#notes}}
|
||||
/// <remarks>
|
||||
/// {{notes}}
|
||||
/// </remarks>
|
||||
{{/notes}}
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}/// <returns>{{#returnType}}{{returnType}}{{/returnType}}</returns>
|
||||
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}}
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// {{notes}}
|
||||
/// </remarks>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}/// <returns>ApiResponse of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object(void){{/returnType}}</returns>
|
||||
ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
{{/operation}}
|
||||
#endregion Synchronous Operations
|
||||
}
|
||||
|
||||
{{#supportsAsync}}
|
||||
/// <summary>
|
||||
/// Represents a collection of functions to interact with the API endpoints
|
||||
/// </summary>
|
||||
{{>visibility}} interface {{interfacePrefix}}{{classname}}Async : IApiAccessor
|
||||
{
|
||||
#region Asynchronous Operations
|
||||
{{#operation}}
|
||||
/// <summary>
|
||||
/// {{summary}}
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// {{notes}}
|
||||
/// </remarks>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}
|
||||
/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <returns>Task of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}</returns>
|
||||
{{#returnType}}System.Threading.Tasks.Task<{{{returnType}}}>{{/returnType}}{{^returnType}}System.Threading.Tasks.Task{{/returnType}} {{operationId}}Async({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}}
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// {{notes}}
|
||||
/// </remarks>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}
|
||||
/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <returns>Task of ApiResponse{{#returnType}} ({{returnType}}){{/returnType}}</returns>
|
||||
System.Threading.Tasks.Task<ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>> {{operationId}}WithHttpInfoAsync({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
{{/operation}}
|
||||
#endregion Asynchronous Operations
|
||||
}
|
||||
{{/supportsAsync}}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of functions to interact with the API endpoints
|
||||
/// </summary>
|
||||
{{>visibility}} interface {{interfacePrefix}}{{classname}} : {{interfacePrefix}}{{classname}}Sync{{#supportsAsync}}, {{interfacePrefix}}{{classname}}Async{{/supportsAsync}}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of functions to interact with the API endpoints
|
||||
/// </summary>
|
||||
{{>visibility}} partial class {{classname}} : {{interfacePrefix}}{{classname}}
|
||||
{
|
||||
private {{packageName}}.Client.ExceptionFactory _exceptionFactory = (name, response) => null;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public {{classname}}() : this((string)null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public {{classname}}(string basePath)
|
||||
{
|
||||
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
|
||||
{{packageName}}.Client.GlobalConfiguration.Instance,
|
||||
new {{packageName}}.Client.Configuration { BasePath = basePath }
|
||||
);
|
||||
this.Client = new {{packageName}}.Client.ApiClient(this.Configuration.BasePath);
|
||||
{{#supportsAsync}}
|
||||
this.AsynchronousClient = new {{packageName}}.Client.ApiClient(this.Configuration.BasePath);
|
||||
{{/supportsAsync}}
|
||||
this.ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class
|
||||
/// using Configuration object
|
||||
/// </summary>
|
||||
/// <param name="configuration">An instance of Configuration</param>
|
||||
/// <returns></returns>
|
||||
public {{classname}}({{packageName}}.Client.Configuration configuration)
|
||||
{
|
||||
if (configuration == null) throw new ArgumentNullException("configuration");
|
||||
|
||||
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
|
||||
{{packageName}}.Client.GlobalConfiguration.Instance,
|
||||
configuration
|
||||
);
|
||||
this.Client = new {{packageName}}.Client.ApiClient(this.Configuration.BasePath);
|
||||
{{#supportsAsync}}
|
||||
this.AsynchronousClient = new {{packageName}}.Client.ApiClient(this.Configuration.BasePath);
|
||||
{{/supportsAsync}}
|
||||
ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class
|
||||
/// using a Configuration object and client instance.
|
||||
/// </summary>
|
||||
/// <param name="client">The client interface for synchronous API access.</param>{{#supportsAsync}}
|
||||
/// <param name="asyncClient">The client interface for asynchronous API access.</param>{{/supportsAsync}}
|
||||
/// <param name="configuration">The configuration object.</param>
|
||||
public {{classname}}({{packageName}}.Client.ISynchronousClient client, {{#supportsAsync}}{{packageName}}.Client.IAsynchronousClient asyncClient, {{/supportsAsync}}{{packageName}}.Client.IReadableConfiguration configuration)
|
||||
{
|
||||
if (client == null) throw new ArgumentNullException("client");
|
||||
{{#supportsAsync}}
|
||||
if (asyncClient == null) throw new ArgumentNullException("asyncClient");
|
||||
{{/supportsAsync}}
|
||||
if (configuration == null) throw new ArgumentNullException("configuration");
|
||||
|
||||
this.Client = client;
|
||||
{{#supportsAsync}}
|
||||
this.AsynchronousClient = asyncClient;
|
||||
{{/supportsAsync}}
|
||||
this.Configuration = configuration;
|
||||
this.ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
|
||||
}
|
||||
|
||||
{{#supportsAsync}}
|
||||
/// <summary>
|
||||
/// The client for accessing this underlying API asynchronously.
|
||||
/// </summary>
|
||||
public {{packageName}}.Client.IAsynchronousClient AsynchronousClient { get; set; }
|
||||
{{/supportsAsync}}
|
||||
|
||||
/// <summary>
|
||||
/// The client for accessing this underlying API synchronously.
|
||||
/// </summary>
|
||||
public {{packageName}}.Client.ISynchronousClient Client { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base path of the API client.
|
||||
/// </summary>
|
||||
/// <value>The base path</value>
|
||||
public string GetBasePath()
|
||||
{
|
||||
return this.Configuration.BasePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration object
|
||||
/// </summary>
|
||||
/// <value>An instance of the Configuration</value>
|
||||
public {{packageName}}.Client.IReadableConfiguration Configuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Provides a factory method hook for the creation of exceptions.
|
||||
/// </summary>
|
||||
public {{packageName}}.Client.ExceptionFactory ExceptionFactory
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_exceptionFactory != null && _exceptionFactory.GetInvocationList().Length > 1)
|
||||
{
|
||||
throw new InvalidOperationException("Multicast delegate for ExceptionFactory is unsupported.");
|
||||
}
|
||||
return _exceptionFactory;
|
||||
}
|
||||
set { _exceptionFactory = value; }
|
||||
}
|
||||
|
||||
{{#operation}}
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}/// <returns>{{#returnType}}{{returnType}}{{/returnType}}</returns>
|
||||
public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||
{
|
||||
{{#returnType}}{{packageName}}.Client.ApiResponse<{{{returnType}}}> localVarResponse = {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
return localVarResponse.Data;{{/returnType}}{{^returnType}}{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});{{/returnType}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}/// <returns>ApiResponse of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object(void){{/returnType}}</returns>
|
||||
public {{packageName}}.Client.ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||
{
|
||||
{{#allParams}}
|
||||
{{#required}}
|
||||
{{^vendorExtensions.x-csharp-value-type}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null)
|
||||
throw new {{packageName}}.Client.ApiException(400, "Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}");
|
||||
|
||||
{{/vendorExtensions.x-csharp-value-type}}
|
||||
{{/required}}
|
||||
{{/allParams}}
|
||||
{{packageName}}.Client.RequestOptions localVarRequestOptions = new {{packageName}}.Client.RequestOptions();
|
||||
|
||||
string[] _contentTypes = new string[] {
|
||||
{{#consumes}}
|
||||
"{{{mediaType}}}"{{^-last}},{{/-last}}
|
||||
{{/consumes}}
|
||||
};
|
||||
|
||||
// to determine the Accept header
|
||||
string[] _accepts = new string[] {
|
||||
{{#produces}}
|
||||
"{{{mediaType}}}"{{^-last}},{{/-last}}
|
||||
{{/produces}}
|
||||
};
|
||||
|
||||
var localVarContentType = {{packageName}}.Client.ClientUtils.SelectHeaderContentType(_contentTypes);
|
||||
if (localVarContentType != null) localVarRequestOptions.HeaderParameters.Add("Content-Type", localVarContentType);
|
||||
|
||||
var localVarAccept = {{packageName}}.Client.ClientUtils.SelectHeaderAccept(_accepts);
|
||||
if (localVarAccept != null) localVarRequestOptions.HeaderParameters.Add("Accept", localVarAccept);
|
||||
|
||||
{{#pathParams}}
|
||||
{{#required}}
|
||||
localVarRequestOptions.PathParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // path parameter
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
localVarRequestOptions.PathParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // path parameter
|
||||
}
|
||||
{{/required}}
|
||||
{{/pathParams}}
|
||||
{{#queryParams}}
|
||||
{{#required}}
|
||||
{{#isDeepObject}}
|
||||
{{#items.vars}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}.{{name}}));
|
||||
{{/items.vars}}
|
||||
{{^items}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("deepObject", "{{baseName}}", {{paramName}}));
|
||||
{{/items}}
|
||||
{{/isDeepObject}}
|
||||
{{^isDeepObject}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
|
||||
{{/isDeepObject}}
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
{{#isDeepObject}}
|
||||
{{#items.vars}}
|
||||
if ({{paramName}}.{{name}} != null)
|
||||
{
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}.{{name}}));
|
||||
}
|
||||
{{/items.vars}}
|
||||
{{^items}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("deepObject", "{{baseName}}", {{paramName}}));
|
||||
{{/items}}
|
||||
{{/isDeepObject}}
|
||||
{{^isDeepObject}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
|
||||
{{/isDeepObject}}
|
||||
}
|
||||
{{/required}}
|
||||
{{/queryParams}}
|
||||
{{#headerParams}}
|
||||
{{#required}}
|
||||
localVarRequestOptions.HeaderParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // header parameter
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // header parameter
|
||||
}
|
||||
{{/required}}
|
||||
{{/headerParams}}
|
||||
{{#formParams}}
|
||||
{{#required}}
|
||||
{{#isFile}}
|
||||
localVarRequestOptions.FileParameters.Add("{{baseName}}", {{paramName}});
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
localVarRequestOptions.FormParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // form parameter
|
||||
{{/isFile}}
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
{{#isFile}}
|
||||
localVarRequestOptions.FileParameters.Add("{{baseName}}", {{paramName}});
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
localVarRequestOptions.FormParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // form parameter
|
||||
{{/isFile}}
|
||||
}
|
||||
{{/required}}
|
||||
{{/formParams}}
|
||||
{{#bodyParam}}
|
||||
localVarRequestOptions.Data = {{paramName}};
|
||||
{{/bodyParam}}
|
||||
|
||||
{{#authMethods}}
|
||||
// authentication ({{name}}) required
|
||||
{{#isApiKey}}
|
||||
{{#isKeyInCookie}}
|
||||
// cookie parameter support
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.Cookies.Add(new Cookie("{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")));
|
||||
}
|
||||
{{/isKeyInCookie}}
|
||||
{{#isKeyInHeader}}
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}"));
|
||||
}
|
||||
{{/isKeyInHeader}}
|
||||
{{#isKeyInQuery}}
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("", "{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")));
|
||||
}
|
||||
{{/isKeyInQuery}}
|
||||
{{/isApiKey}}
|
||||
{{#isBasicBasic}}
|
||||
// http basic authentication required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.Username) || !string.IsNullOrEmpty(this.Configuration.Password))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Basic " + {{packageName}}.Client.ClientUtils.Base64Encode(this.Configuration.Username + ":" + this.Configuration.Password));
|
||||
}
|
||||
{{/isBasicBasic}}
|
||||
{{#isBasicBearer}}
|
||||
// bearer authentication required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.AccessToken))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Bearer " + this.Configuration.AccessToken);
|
||||
}
|
||||
{{/isBasicBearer}}
|
||||
{{#isOAuth}}
|
||||
// oauth required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.AccessToken))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Bearer " + this.Configuration.AccessToken);
|
||||
}
|
||||
{{/isOAuth}}
|
||||
{{#isHttpSignature}}
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "{{{httpMethod}}}", "{{{path}}}", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters[headerItem.Key] = new List<string>() { headerItem.Value };
|
||||
}
|
||||
else
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add(headerItem.Key, headerItem.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
{{/isHttpSignature}}
|
||||
{{/authMethods}}
|
||||
|
||||
// make the HTTP request
|
||||
var localVarResponse = this.Client.{{#lambda.titlecase}}{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}{{/lambda.titlecase}}<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>("{{{path}}}", localVarRequestOptions, this.Configuration);
|
||||
|
||||
if (this.ExceptionFactory != null)
|
||||
{
|
||||
Exception _exception = this.ExceptionFactory("{{operationId}}", localVarResponse);
|
||||
if (_exception != null) throw _exception;
|
||||
}
|
||||
|
||||
return localVarResponse;
|
||||
}
|
||||
|
||||
{{#supportsAsync}}
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}
|
||||
/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <returns>Task of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}</returns>
|
||||
{{#returnType}}public async System.Threading.Tasks.Task<{{{returnType}}}>{{/returnType}}{{^returnType}}public async System.Threading.Tasks.Task{{/returnType}} {{operationId}}Async({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
{{#returnType}}{{packageName}}.Client.ApiResponse<{{{returnType}}}> localVarResponse = await {{operationId}}WithHttpInfoAsync({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}cancellationToken).ConfigureAwait(false);
|
||||
return localVarResponse.Data;{{/returnType}}{{^returnType}}await {{operationId}}WithHttpInfoAsync({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}cancellationToken).ConfigureAwait(false);{{/returnType}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}
|
||||
/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <returns>Task of ApiResponse{{#returnType}} ({{returnType}}){{/returnType}}</returns>
|
||||
public async System.Threading.Tasks.Task<{{packageName}}.Client.ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>> {{operationId}}WithHttpInfoAsync({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
{{#allParams}}
|
||||
{{#required}}
|
||||
{{^vendorExtensions.x-csharp-value-type}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null)
|
||||
throw new {{packageName}}.Client.ApiException(400, "Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}");
|
||||
|
||||
{{/vendorExtensions.x-csharp-value-type}}
|
||||
{{/required}}
|
||||
{{/allParams}}
|
||||
|
||||
{{packageName}}.Client.RequestOptions localVarRequestOptions = new {{packageName}}.Client.RequestOptions();
|
||||
|
||||
string[] _contentTypes = new string[] {
|
||||
{{#consumes}}
|
||||
"{{{mediaType}}}"{{^-last}}, {{/-last}}
|
||||
{{/consumes}}
|
||||
};
|
||||
|
||||
// to determine the Accept header
|
||||
string[] _accepts = new string[] {
|
||||
{{#produces}}
|
||||
"{{{mediaType}}}"{{^-last}},{{/-last}}
|
||||
{{/produces}}
|
||||
};
|
||||
|
||||
|
||||
var localVarContentType = {{packageName}}.Client.ClientUtils.SelectHeaderContentType(_contentTypes);
|
||||
if (localVarContentType != null) localVarRequestOptions.HeaderParameters.Add("Content-Type", localVarContentType);
|
||||
|
||||
var localVarAccept = {{packageName}}.Client.ClientUtils.SelectHeaderAccept(_accepts);
|
||||
if (localVarAccept != null) localVarRequestOptions.HeaderParameters.Add("Accept", localVarAccept);
|
||||
|
||||
{{#pathParams}}
|
||||
{{#required}}
|
||||
localVarRequestOptions.PathParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // path parameter
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
localVarRequestOptions.PathParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // path parameter
|
||||
}
|
||||
{{/required}}
|
||||
{{/pathParams}}
|
||||
{{#queryParams}}
|
||||
{{#required}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
|
||||
}
|
||||
{{/required}}
|
||||
{{/queryParams}}
|
||||
{{#headerParams}}
|
||||
{{#required}}
|
||||
localVarRequestOptions.HeaderParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // header parameter
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // header parameter
|
||||
}
|
||||
{{/required}}
|
||||
{{/headerParams}}
|
||||
{{#formParams}}
|
||||
{{#required}}
|
||||
{{#isFile}}
|
||||
localVarRequestOptions.FileParameters.Add("{{baseName}}", {{paramName}});
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
localVarRequestOptions.FormParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // form parameter
|
||||
{{/isFile}}
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
{{#isFile}}
|
||||
localVarRequestOptions.FileParameters.Add("{{baseName}}", {{paramName}});
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
localVarRequestOptions.FormParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // form parameter
|
||||
{{/isFile}}
|
||||
}
|
||||
{{/required}}
|
||||
{{/formParams}}
|
||||
{{#bodyParam}}
|
||||
localVarRequestOptions.Data = {{paramName}};
|
||||
{{/bodyParam}}
|
||||
|
||||
{{#authMethods}}
|
||||
// authentication ({{name}}) required
|
||||
{{#isApiKey}}
|
||||
{{#isKeyInCookie}}
|
||||
// cookie parameter support
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.Cookies.Add(new Cookie("{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")));
|
||||
}
|
||||
{{/isKeyInCookie}}
|
||||
{{#isKeyInHeader}}
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}"));
|
||||
}
|
||||
{{/isKeyInHeader}}
|
||||
{{#isKeyInQuery}}
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("", "{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")));
|
||||
}
|
||||
{{/isKeyInQuery}}
|
||||
{{/isApiKey}}
|
||||
{{#isBasic}}
|
||||
{{#isBasicBasic}}
|
||||
// http basic authentication required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.Username) || !string.IsNullOrEmpty(this.Configuration.Password))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Basic " + {{packageName}}.Client.ClientUtils.Base64Encode(this.Configuration.Username + ":" + this.Configuration.Password));
|
||||
}
|
||||
{{/isBasicBasic}}
|
||||
{{#isBasicBearer}}
|
||||
// bearer authentication required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.AccessToken))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Bearer " + this.Configuration.AccessToken);
|
||||
}
|
||||
{{/isBasicBearer}}
|
||||
{{/isBasic}}
|
||||
{{#isOAuth}}
|
||||
// oauth required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.AccessToken))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Bearer " + this.Configuration.AccessToken);
|
||||
}
|
||||
{{/isOAuth}}
|
||||
{{#isHttpSignature}}
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "{{{httpMethod}}}", "{{{path}}}", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters[headerItem.Key] = new List<string>() { headerItem.Value };
|
||||
}
|
||||
else
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add(headerItem.Key, headerItem.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
{{/isHttpSignature}}
|
||||
{{/authMethods}}
|
||||
|
||||
// make the HTTP request
|
||||
|
||||
var localVarResponse = await this.AsynchronousClient.{{#lambda.titlecase}}{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}{{/lambda.titlecase}}Async<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>("{{{path}}}", localVarRequestOptions, this.Configuration, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (this.ExceptionFactory != null)
|
||||
{
|
||||
Exception _exception = this.ExceptionFactory("{{operationId}}", localVarResponse);
|
||||
if (_exception != null) throw _exception;
|
||||
}
|
||||
|
||||
return localVarResponse;
|
||||
}
|
||||
|
||||
{{/supportsAsync}}
|
||||
{{/operation}}
|
||||
}
|
||||
{{/operations}}
|
||||
}
|
134
modules/openapi-generator/src/main/resources/csharp-netcore-functions/api_doc.mustache
vendored
Normal file
134
modules/openapi-generator/src/main/resources/csharp-netcore-functions/api_doc.mustache
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
# {{packageName}}.{{apiPackage}}.{{classname}}{{#description}}
|
||||
{{description}}{{/description}}
|
||||
|
||||
All URIs are relative to *{{{basePath}}}*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
|
||||
{{/operation}}{{/operations}}
|
||||
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
<a name="{{{operationIdLowerCase}}}"></a>
|
||||
# **{{{operationId}}}**
|
||||
> {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}} ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||
|
||||
{{{summary}}}{{#notes}}
|
||||
|
||||
{{{notes}}}{{/notes}}
|
||||
|
||||
### Example
|
||||
```csharp
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
{{#useHttpClient}}
|
||||
using System.Net.Http;
|
||||
{{/useHttpClient}}
|
||||
using {{packageName}}.{{apiPackage}};
|
||||
using {{packageName}}.Client;
|
||||
using {{packageName}}.{{modelPackage}};
|
||||
|
||||
namespace Example
|
||||
{
|
||||
public class {{operationId}}Example
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
Configuration config = new Configuration();
|
||||
config.BasePath = "{{{basePath}}}";
|
||||
{{#hasAuthMethods}}
|
||||
{{#authMethods}}
|
||||
{{#isBasicBasic}}
|
||||
// Configure HTTP basic authorization: {{{name}}}
|
||||
config.Username = "YOUR_USERNAME";
|
||||
config.Password = "YOUR_PASSWORD";
|
||||
{{/isBasicBasic}}
|
||||
{{#isBasicBearer}}
|
||||
// Configure Bearer token for authorization: {{{name}}}
|
||||
config.AccessToken = "YOUR_BEARER_TOKEN";
|
||||
{{/isBasicBearer}}
|
||||
{{#isApiKey}}
|
||||
// Configure API key authorization: {{{name}}}
|
||||
config.AddApiKey("{{{keyParamName}}}", "YOUR_API_KEY");
|
||||
// Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||
// config.AddApiKeyPrefix("{{{keyParamName}}}", "Bearer");
|
||||
{{/isApiKey}}
|
||||
{{#isOAuth}}
|
||||
// Configure OAuth2 access token for authorization: {{{name}}}
|
||||
config.AccessToken = "YOUR_ACCESS_TOKEN";
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
|
||||
{{/hasAuthMethods}}
|
||||
{{#useHttpClient}}
|
||||
// create instances of HttpClient, HttpClientHandler to be reused later with different Api classes
|
||||
HttpClient httpClient = new HttpClient();
|
||||
HttpClientHandler httpClientHandler = new HttpClientHandler();
|
||||
var apiInstance = new {{classname}}(httpClient, config, httpClientHandler);
|
||||
{{/useHttpClient}}
|
||||
{{^useHttpClient}}
|
||||
var apiInstance = new {{classname}}(config);
|
||||
{{/useHttpClient}}
|
||||
{{#allParams}}
|
||||
{{#isPrimitiveType}}
|
||||
var {{paramName}} = {{{example}}}; // {{{dataType}}} | {{{description}}}{{^required}} (optional) {{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
var {{paramName}} = new {{{dataType}}}(); // {{{dataType}}} | {{{description}}}{{^required}} (optional) {{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/allParams}}
|
||||
|
||||
try
|
||||
{
|
||||
{{#summary}}
|
||||
// {{{.}}}
|
||||
{{/summary}}
|
||||
{{#returnType}}{{{returnType}}} result = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});{{#returnType}}
|
||||
Debug.WriteLine(result);{{/returnType}}
|
||||
}
|
||||
catch (ApiException e)
|
||||
{
|
||||
Debug.Print("Exception when calling {{classname}}.{{operationId}}: " + e.Message );
|
||||
Debug.Print("Status Code: "+ e.ErrorCode);
|
||||
Debug.Print(e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}}
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}
|
||||
{{#allParams}} **{{paramName}}** | {{#isFile}}**{{dataType}}**{{/isFile}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{^isFile}}[**{{dataType}}**]({{#isContainer}}{{baseType}}{{/isContainer}}{{^isContainer}}{{dataType}}{{/isContainer}}.md){{/isFile}}{{/isPrimitiveType}}| {{description}} | {{^required}}[optional] {{/required}}{{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}
|
||||
{{/allParams}}
|
||||
|
||||
### Return type
|
||||
|
||||
{{#returnType}}{{#returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{returnType}}**]({{returnBaseType}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void (empty response body){{/returnType}}
|
||||
|
||||
### Authorization
|
||||
|
||||
{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{{name}}}](../README.md#{{{name}}}){{^-last}}, {{/-last}}{{/authMethods}}
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: {{#consumes}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
|
||||
- **Accept**: {{#produces}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}}
|
||||
|
||||
{{#responses.0}}
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
{{#responses}}
|
||||
| **{{code}}** | {{message}} | {{#headers}} * {{baseName}} - {{description}} <br> {{/headers}}{{^headers.0}} - {{/headers.0}} |
|
||||
{{/responses}}
|
||||
{{/responses.0}}
|
||||
|
||||
[[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)
|
||||
|
||||
{{/operation}}
|
||||
{{/operations}}
|
73
modules/openapi-generator/src/main/resources/csharp-netcore-functions/api_test.mustache
vendored
Normal file
73
modules/openapi-generator/src/main/resources/csharp-netcore-functions/api_test.mustache
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
{{>partial_header}}
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
{{#useRestSharp}}
|
||||
using RestSharp;
|
||||
{{/useRestSharp}}
|
||||
using Xunit;
|
||||
|
||||
using {{packageName}}.Client;
|
||||
using {{packageName}}.{{apiPackage}};
|
||||
{{#hasImport}}
|
||||
// uncomment below to import models
|
||||
//using {{packageName}}.{{modelPackage}};
|
||||
{{/hasImport}}
|
||||
|
||||
namespace {{packageName}}.Test.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for testing {{classname}}
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This file is automatically generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
/// Please update the test case below to test the API endpoint.
|
||||
/// </remarks>
|
||||
public class {{classname}}Tests : IDisposable
|
||||
{
|
||||
private {{classname}} instance;
|
||||
|
||||
public {{classname}}Tests()
|
||||
{
|
||||
instance = new {{classname}}();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Cleanup when everything is done.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test an instance of {{classname}}
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void {{operationId}}InstanceTest()
|
||||
{
|
||||
// TODO uncomment below to test 'IsType' {{classname}}
|
||||
//Assert.IsType<{{classname}}>(instance);
|
||||
}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
|
||||
/// <summary>
|
||||
/// Test {{operationId}}
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void {{operationId}}Test()
|
||||
{
|
||||
// TODO uncomment below to test the method and replace null with proper value
|
||||
{{#allParams}}
|
||||
//{{{dataType}}} {{paramName}} = null;
|
||||
{{/allParams}}
|
||||
//{{#returnType}}var response = {{/returnType}}instance.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
{{#returnType}}
|
||||
//Assert.IsType<{{{returnType}}}>(response);
|
||||
{{/returnType}}
|
||||
}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
}
|
||||
}
|
9
modules/openapi-generator/src/main/resources/csharp-netcore-functions/appveyor.mustache
vendored
Normal file
9
modules/openapi-generator/src/main/resources/csharp-netcore-functions/appveyor.mustache
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# auto-generated by OpenAPI Generator (https://github.com/OpenAPITools/openapi-generator)
|
||||
#
|
||||
image: Visual Studio 2019
|
||||
clone_depth: 1
|
||||
build_script:
|
||||
- dotnet build -c Release
|
||||
- dotnet test -c Release
|
||||
after_build:
|
||||
- dotnet pack .\src\{{{packageName}}}\{{{packageName}}}.csproj -o ../../output -c Release --no-build
|
28
modules/openapi-generator/src/main/resources/csharp-netcore-functions/functions.mustache
vendored
Normal file
28
modules/openapi-generator/src/main/resources/csharp-netcore-functions/functions.mustache
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Azure.WebJobs;
|
||||
using Microsoft.Azure.WebJobs.Extensions.Http;
|
||||
|
||||
namespace {{packageName}}.{{apiPackage}}
|
||||
{ {{#operations}}
|
||||
public partial {{#classModifier}}{{classModifier}} {{/classModifier}}class {{classname}}
|
||||
{ {{#operation}}
|
||||
[FunctionName("{{classname}}_{{operationId}}")]
|
||||
public async Task<IActionResult> _{{operationId}}([HttpTrigger(AuthorizationLevel.Anonymous, "{{httpMethod}}", Route = "{{{apiBasePath}}}{{{path}}}")]HttpRequest req, ExecutionContext context{{#allParams}}{{#isPathParam}}, {{>pathParam}}{{/isPathParam}}{{/allParams}})
|
||||
{
|
||||
var method = this.GetType().GetMethod("{{operationId}}");
|
||||
|
||||
return method != null
|
||||
? (await ((Task<IActionResult>)method.Invoke(this, new object[] { req, context{{#allParams}}{{#isPathParam}}, {{/isPathParam}}{{/allParams}} })).ConfigureAwait(false))
|
||||
: new StatusCodeResult((int)HttpStatusCode.NotImplemented);
|
||||
}
|
||||
{{/operation}}
|
||||
}
|
||||
}
|
||||
{{/operations}}
|
||||
|
58
modules/openapi-generator/src/main/resources/csharp-netcore-functions/git_push.sh.mustache
vendored
Normal file
58
modules/openapi-generator/src/main/resources/csharp-netcore-functions/git_push.sh.mustache
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
|
||||
#
|
||||
# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" "gitlab.com"
|
||||
|
||||
git_user_id=$1
|
||||
git_repo_id=$2
|
||||
release_note=$3
|
||||
git_host=$4
|
||||
|
||||
if [ "$git_host" = "" ]; then
|
||||
git_host="{{{gitHost}}}"
|
||||
echo "[INFO] No command line input provided. Set \$git_host to $git_host"
|
||||
fi
|
||||
|
||||
if [ "$git_user_id" = "" ]; then
|
||||
git_user_id="{{{gitUserId}}}"
|
||||
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
|
||||
fi
|
||||
|
||||
if [ "$git_repo_id" = "" ]; then
|
||||
git_repo_id="{{{gitRepoId}}}"
|
||||
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
|
||||
fi
|
||||
|
||||
if [ "$release_note" = "" ]; then
|
||||
release_note="{{{releaseNote}}}"
|
||||
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
|
||||
fi
|
||||
|
||||
# Initialize the local directory as a Git repository
|
||||
git init
|
||||
|
||||
# Adds the files in the local repository and stages them for commit.
|
||||
git add .
|
||||
|
||||
# Commits the tracked changes and prepares them to be pushed to a remote repository.
|
||||
git commit -m "$release_note"
|
||||
|
||||
# Sets the new remote
|
||||
git_remote=`git remote`
|
||||
if [ "$git_remote" = "" ]; then # git remote not defined
|
||||
|
||||
if [ "$GIT_TOKEN" = "" ]; then
|
||||
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
|
||||
git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git
|
||||
else
|
||||
git remote add origin https://${git_user_id}:${GIT_TOKEN}@${git_host}/${git_user_id}/${git_repo_id}.git
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
git pull origin master
|
||||
|
||||
# Pushes (Forces) the changes in the local repository up to the remote repository
|
||||
echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git"
|
||||
git push origin master 2>&1 | grep -v 'To https'
|
||||
|
362
modules/openapi-generator/src/main/resources/csharp-netcore-functions/gitignore.mustache
vendored
Normal file
362
modules/openapi-generator/src/main/resources/csharp-netcore-functions/gitignore.mustache
vendored
Normal file
@ -0,0 +1,362 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
@ -0,0 +1,739 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
{{^netStandard}}
|
||||
using System.Web;
|
||||
{{/netStandard}}
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
||||
{{#useWebRequest}}
|
||||
using System.Net.Http;
|
||||
{{/useWebRequest}}
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
{{#supportsRetry}}
|
||||
using Polly;
|
||||
{{/supportsRetry}}
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// To Serialize/Deserialize JSON using our custom logic, but only when ContentType is JSON.
|
||||
/// </summary>
|
||||
internal class CustomJsonCodec
|
||||
{
|
||||
private readonly IReadableConfiguration _configuration;
|
||||
private static readonly string _contentType = "application/json";
|
||||
private readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
// OpenAPI generated types generally hide default constructors.
|
||||
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy
|
||||
{
|
||||
OverrideSpecifiedNames = false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public CustomJsonCodec(IReadableConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfiguration configuration)
|
||||
{
|
||||
_serializerSettings = serializerSettings;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize the object into a JSON string.
|
||||
/// </summary>
|
||||
/// <param name="obj">Object to be serialized.</param>
|
||||
/// <returns>A JSON string.</returns>
|
||||
public string Serialize(object obj)
|
||||
{
|
||||
if (obj != null && obj is {{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema)
|
||||
{
|
||||
// the object to be serialized is an oneOf/anyOf schema
|
||||
return (({{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema)obj).ToJson();
|
||||
}
|
||||
else
|
||||
{
|
||||
return JsonConvert.SerializeObject(obj, _serializerSettings);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<T> Deserialize<T>(HttpResponseMessage response)
|
||||
{
|
||||
var result = (T) await Deserialize(response, typeof(T));
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize the JSON string into a proper object.
|
||||
/// </summary>
|
||||
/// <param name="response">The HTTP response.</param>
|
||||
/// <param name="type">Object type.</param>
|
||||
/// <returns>Object representation of the JSON string.</returns>
|
||||
internal async Task<object> Deserialize(HttpResponseMessage response, Type type)
|
||||
{
|
||||
IList<string> headers = response.Headers.Select(x => x.Key + "=" + x.Value).ToList();
|
||||
|
||||
if (type == typeof(byte[])) // return byte array
|
||||
{
|
||||
return await response.Content.ReadAsByteArrayAsync();
|
||||
}
|
||||
|
||||
// TODO: ? if (type.IsAssignableFrom(typeof(Stream)))
|
||||
if (type == typeof(Stream))
|
||||
{
|
||||
var bytes = await response.Content.ReadAsByteArrayAsync();
|
||||
if (headers != null)
|
||||
{
|
||||
var filePath = string.IsNullOrEmpty(_configuration.TempFolderPath)
|
||||
? Path.GetTempPath()
|
||||
: _configuration.TempFolderPath;
|
||||
var regex = new Regex(@"Content-Disposition=.*filename=['""]?([^'""\s]+)['""]?$");
|
||||
foreach (var header in headers)
|
||||
{
|
||||
var match = regex.Match(header.ToString());
|
||||
if (match.Success)
|
||||
{
|
||||
string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", ""));
|
||||
File.WriteAllBytes(fileName, bytes);
|
||||
return new FileStream(fileName, FileMode.Open);
|
||||
}
|
||||
}
|
||||
}
|
||||
var stream = new MemoryStream(bytes);
|
||||
return stream;
|
||||
}
|
||||
|
||||
if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object
|
||||
{
|
||||
return DateTime.Parse(await response.Content.ReadAsStringAsync(), null, System.Globalization.DateTimeStyles.RoundtripKind);
|
||||
}
|
||||
|
||||
if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type
|
||||
{
|
||||
return Convert.ChangeType(await response.Content.ReadAsStringAsync(), type);
|
||||
}
|
||||
|
||||
// at this point, it must be a model (json)
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync(), type, _serializerSettings);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApiException(500, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public string RootElement { get; set; }
|
||||
public string Namespace { get; set; }
|
||||
public string DateFormat { get; set; }
|
||||
|
||||
public string ContentType
|
||||
{
|
||||
get { return _contentType; }
|
||||
set { throw new InvalidOperationException("Not allowed to set content type."); }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Provides a default implementation of an Api client (both synchronous and asynchronous implementatios),
|
||||
/// encapsulating general REST accessor use cases.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The Dispose method will manage the HttpClient lifecycle when not passed by constructor.
|
||||
/// </remarks>
|
||||
{{>visibility}} partial class ApiClient : IDisposable, ISynchronousClient{{#supportsAsync}}, IAsynchronousClient{{/supportsAsync}}
|
||||
{
|
||||
private readonly string _baseUrl;
|
||||
|
||||
private readonly HttpClientHandler _httpClientHandler;
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly bool _disposeClient;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the settings on a <see cref="JsonSerializer" /> object.
|
||||
/// These settings can be adjusted to accomodate custom serialization rules.
|
||||
/// </summary>
|
||||
public JsonSerializerSettings SerializerSettings { get; set; } = new JsonSerializerSettings
|
||||
{
|
||||
// OpenAPI generated types generally hide default constructors.
|
||||
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy
|
||||
{
|
||||
OverrideSpecifiedNames = false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiClient" />, defaulting to the global configurations' base url.
|
||||
/// **IMPORTANT** This will also create an istance of HttpClient, which is less than ideal.
|
||||
/// It's better to reuse the <see href="https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests#issues-with-the-original-httpclient-class-available-in-net">HttpClient and HttpClientHander</see>.
|
||||
/// </summary>
|
||||
public ApiClient() :
|
||||
this({{packageName}}.Client.GlobalConfiguration.Instance.BasePath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiClient" />.
|
||||
/// **IMPORTANT** This will also create an istance of HttpClient, which is less than ideal.
|
||||
/// It's better to reuse the <see href="https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests#issues-with-the-original-httpclient-class-available-in-net">HttpClient and HttpClientHander</see>.
|
||||
/// </summary>
|
||||
/// <param name="basePath">The target service's base path in URL format.</param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public ApiClient(string basePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(basePath)) throw new ArgumentException("basePath cannot be empty");
|
||||
|
||||
_httpClientHandler = new HttpClientHandler();
|
||||
_httpClient = new HttpClient(_httpClientHandler, true);
|
||||
_disposeClient = true;
|
||||
_baseUrl = basePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiClient" />, defaulting to the global configurations' base url.
|
||||
/// </summary>
|
||||
/// <param name="client">An instance of HttpClient.</param>
|
||||
/// <param name="handler">An optional instance of HttpClientHandler that is used by HttpClient.</param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <remarks>
|
||||
/// Some configuration settings will not be applied without passing an HttpClientHandler.
|
||||
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
|
||||
/// </remarks>
|
||||
public ApiClient(HttpClient client, HttpClientHandler handler = null) :
|
||||
this(client, {{packageName}}.Client.GlobalConfiguration.Instance.BasePath, handler)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiClient" />.
|
||||
/// </summary>
|
||||
/// <param name="client">An instance of HttpClient.</param>
|
||||
/// <param name="basePath">The target service's base path in URL format.</param>
|
||||
/// <param name="handler">An optional instance of HttpClientHandler that is used by HttpClient.</param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
/// <remarks>
|
||||
/// Some configuration settings will not be applied without passing an HttpClientHandler.
|
||||
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
|
||||
/// </remarks>
|
||||
public ApiClient(HttpClient client, string basePath, HttpClientHandler handler = null)
|
||||
{
|
||||
if (client == null) throw new ArgumentNullException("client cannot be null");
|
||||
if (string.IsNullOrEmpty(basePath)) throw new ArgumentException("basePath cannot be empty");
|
||||
|
||||
_httpClientHandler = handler;
|
||||
_httpClient = client;
|
||||
_baseUrl = basePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes resources if they were created by us
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if(_disposeClient) {
|
||||
_httpClient.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// Prepares multipart/form-data content
|
||||
{{! TODO: Add handling of improper usage }}
|
||||
HttpContent PrepareMultipartFormDataContent(RequestOptions options)
|
||||
{
|
||||
string boundary = "---------" + Guid.NewGuid().ToString().ToUpperInvariant();
|
||||
var multipartContent = new MultipartFormDataContent(boundary);
|
||||
foreach (var formParameter in options.FormParameters)
|
||||
{
|
||||
multipartContent.Add(new StringContent(formParameter.Value), formParameter.Key);
|
||||
}
|
||||
|
||||
if (options.FileParameters != null && options.FileParameters.Count > 0)
|
||||
{
|
||||
foreach (var fileParam in options.FileParameters)
|
||||
{
|
||||
var content = new StreamContent(fileParam.Value.Content);
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||
multipartContent.Add(content, fileParam.Key,
|
||||
fileParam.Value.Name);
|
||||
}
|
||||
}
|
||||
return multipartContent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides all logic for constructing a new HttpRequestMessage.
|
||||
/// At this point, all information for querying the service is known. Here, it is simply
|
||||
/// mapped into the a HttpRequestMessage.
|
||||
/// </summary>
|
||||
/// <param name="method">The http verb.</param>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>[private] A new HttpRequestMessage instance.</returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
private HttpRequestMessage NewRequest(
|
||||
HttpMethod method,
|
||||
string path,
|
||||
RequestOptions options,
|
||||
IReadableConfiguration configuration)
|
||||
{
|
||||
if (path == null) throw new ArgumentNullException("path");
|
||||
if (options == null) throw new ArgumentNullException("options");
|
||||
if (configuration == null) throw new ArgumentNullException("configuration");
|
||||
|
||||
WebRequestPathBuilder builder = new WebRequestPathBuilder(_baseUrl, path);
|
||||
|
||||
builder.AddPathParameters(options.PathParameters);
|
||||
|
||||
builder.AddQueryParameters(options.QueryParameters);
|
||||
|
||||
HttpRequestMessage request = new HttpRequestMessage(method, builder.GetFullUri());
|
||||
|
||||
if (configuration.UserAgent != null)
|
||||
{
|
||||
request.Headers.TryAddWithoutValidation("User-Agent", configuration.UserAgent);
|
||||
}
|
||||
|
||||
if (configuration.DefaultHeaders != null)
|
||||
{
|
||||
foreach (var headerParam in configuration.DefaultHeaders)
|
||||
{
|
||||
request.Headers.Add(headerParam.Key, headerParam.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.HeaderParameters != null)
|
||||
{
|
||||
foreach (var headerParam in options.HeaderParameters)
|
||||
{
|
||||
foreach (var value in headerParam.Value)
|
||||
{
|
||||
// Todo make content headers actually content headers
|
||||
request.Headers.TryAddWithoutValidation(headerParam.Key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Tuple<HttpContent, string, string>> contentList = new List<Tuple<HttpContent, string, string>>();
|
||||
|
||||
string contentType = null;
|
||||
if (options.HeaderParameters != null && options.HeaderParameters.ContainsKey("Content-Type"))
|
||||
{
|
||||
var contentTypes = options.HeaderParameters["Content-Type"];
|
||||
contentType = contentTypes.FirstOrDefault();
|
||||
}
|
||||
|
||||
{{!// TODO Add error handling in case of improper usage}}
|
||||
if (contentType == "multipart/form-data")
|
||||
{
|
||||
request.Content = PrepareMultipartFormDataContent(options);
|
||||
}
|
||||
else if (contentType == "application/x-www-form-urlencoded")
|
||||
{
|
||||
request.Content = new FormUrlEncodedContent(options.FormParameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (options.Data != null)
|
||||
{
|
||||
if (options.Data is FileParameter fp)
|
||||
{
|
||||
contentType = contentType ?? "application/octet-stream";
|
||||
|
||||
var streamContent = new StreamContent(fp.Content);
|
||||
streamContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
request.Content = streamContent;
|
||||
}
|
||||
else
|
||||
{
|
||||
var serializer = new CustomJsonCodec(SerializerSettings, configuration);
|
||||
request.Content = new StringContent(serializer.Serialize(options.Data), new UTF8Encoding(),
|
||||
"application/json");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO provide an alternative that allows cookies per request instead of per API client
|
||||
if (options.Cookies != null && options.Cookies.Count > 0)
|
||||
{
|
||||
request.Properties["CookieContainer"] = options.Cookies;
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
partial void InterceptRequest(HttpRequestMessage req);
|
||||
partial void InterceptResponse(HttpRequestMessage req, HttpResponseMessage response);
|
||||
|
||||
private async Task<ApiResponse<T>> ToApiResponse<T>(HttpResponseMessage response, object responseData, Uri uri)
|
||||
{
|
||||
T result = (T) responseData;
|
||||
string rawContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
var transformed = new ApiResponse<T>(response.StatusCode, new Multimap<string, string>({{#caseInsensitiveResponseHeaders}}StringComparer.OrdinalIgnoreCase{{/caseInsensitiveResponseHeaders}}), result, rawContent)
|
||||
{
|
||||
ErrorText = response.ReasonPhrase,
|
||||
Cookies = new List<Cookie>()
|
||||
};
|
||||
|
||||
// process response headers, e.g. Access-Control-Allow-Methods
|
||||
if (response.Headers != null)
|
||||
{
|
||||
foreach (var responseHeader in response.Headers)
|
||||
{
|
||||
transformed.Headers.Add(responseHeader.Key, ClientUtils.ParameterToString(responseHeader.Value));
|
||||
}
|
||||
}
|
||||
|
||||
// process response content headers, e.g. Content-Type
|
||||
if (response.Content.Headers != null)
|
||||
{
|
||||
foreach (var responseHeader in response.Content.Headers)
|
||||
{
|
||||
transformed.Headers.Add(responseHeader.Key, ClientUtils.ParameterToString(responseHeader.Value));
|
||||
}
|
||||
}
|
||||
|
||||
if (_httpClientHandler != null && response != null)
|
||||
{
|
||||
try {
|
||||
foreach (Cookie cookie in _httpClientHandler.CookieContainer.GetCookies(uri))
|
||||
{
|
||||
transformed.Cookies.Add(cookie);
|
||||
}
|
||||
}
|
||||
catch (PlatformNotSupportedException) {}
|
||||
}
|
||||
|
||||
return transformed;
|
||||
}
|
||||
|
||||
private ApiResponse<T> Exec<T>(HttpRequestMessage req, IReadableConfiguration configuration)
|
||||
{
|
||||
return ExecAsync<T>(req, configuration).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private async Task<ApiResponse<T>> ExecAsync<T>(HttpRequestMessage req,
|
||||
IReadableConfiguration configuration,
|
||||
System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var deserializer = new CustomJsonCodec(SerializerSettings, configuration);
|
||||
|
||||
var finalToken = cancellationToken;
|
||||
|
||||
if (configuration.Timeout > 0)
|
||||
{
|
||||
var tokenSource = new CancellationTokenSource(configuration.Timeout);
|
||||
finalToken = CancellationTokenSource.CreateLinkedTokenSource(finalToken, tokenSource.Token).Token;
|
||||
}
|
||||
|
||||
if (configuration.Proxy != null)
|
||||
{
|
||||
if(_httpClientHandler == null) throw new InvalidOperationException("Configuration `Proxy` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor.");
|
||||
_httpClientHandler.Proxy = configuration.Proxy;
|
||||
}
|
||||
|
||||
if (configuration.ClientCertificates != null)
|
||||
{
|
||||
if(_httpClientHandler == null) throw new InvalidOperationException("Configuration `ClientCertificates` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor.");
|
||||
_httpClientHandler.ClientCertificates.AddRange(configuration.ClientCertificates);
|
||||
}
|
||||
|
||||
var cookieContainer = req.Properties.ContainsKey("CookieContainer") ? req.Properties["CookieContainer"] as List<Cookie> : null;
|
||||
|
||||
if (cookieContainer != null)
|
||||
{
|
||||
if(_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor.");
|
||||
foreach (var cookie in cookieContainer)
|
||||
{
|
||||
_httpClientHandler.CookieContainer.Add(cookie);
|
||||
}
|
||||
}
|
||||
|
||||
InterceptRequest(req);
|
||||
|
||||
HttpResponseMessage response;
|
||||
{{#supportsRetry}}
|
||||
if (RetryConfiguration.AsyncRetryPolicy != null)
|
||||
{
|
||||
var policy = RetryConfiguration.AsyncRetryPolicy;
|
||||
var policyResult = await policy
|
||||
.ExecuteAndCaptureAsync(() => _httpClient.SendAsync(req, cancellationToken))
|
||||
.ConfigureAwait(false);
|
||||
response = (policyResult.Outcome == OutcomeType.Successful) ?
|
||||
policyResult.Result : new HttpResponseMessage()
|
||||
{
|
||||
ReasonPhrase = policyResult.FinalException.ToString(),
|
||||
RequestMessage = req
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
{{/supportsRetry}}
|
||||
response = await _httpClient.SendAsync(req, cancellationToken).ConfigureAwait(false);
|
||||
{{#supportsRetry}}
|
||||
}
|
||||
{{/supportsRetry}}
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return await ToApiResponse<T>(response, default(T), req.RequestUri);
|
||||
}
|
||||
|
||||
object responseData = await deserializer.Deserialize<T>(response);
|
||||
|
||||
// if the response type is oneOf/anyOf, call FromJSON to deserialize the data
|
||||
if (typeof({{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
responseData = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
|
||||
}
|
||||
else if (typeof(T).Name == "Stream") // for binary response
|
||||
{
|
||||
responseData = (T) (object) await response.Content.ReadAsStreamAsync();
|
||||
}
|
||||
|
||||
InterceptResponse(req, response);
|
||||
|
||||
return await ToApiResponse<T>(response, responseData, req.RequestUri);
|
||||
}
|
||||
|
||||
{{#supportsAsync}}
|
||||
#region IAsynchronousClient
|
||||
/// <summary>
|
||||
/// Make a HTTP GET request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> GetAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Get, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP POST request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> PostAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Post, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP PUT request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> PutAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Put, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP DELETE request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> DeleteAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Delete, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP HEAD request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> HeadAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Head, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP OPTION request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> OptionsAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(HttpMethod.Options, path, options, config), config, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP PATCH request (async).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <param name="cancellationToken">Token that enables callers to cancel the request.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public Task<ApiResponse<T>> PatchAsync<T>(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return ExecAsync<T>(NewRequest(new HttpMethod("PATCH"), path, options, config), config, cancellationToken);
|
||||
}
|
||||
#endregion IAsynchronousClient
|
||||
{{/supportsAsync}}
|
||||
|
||||
#region ISynchronousClient
|
||||
/// <summary>
|
||||
/// Make a HTTP GET request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Get<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Get, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP POST request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Post<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Post, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP PUT request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Put<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Put, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP DELETE request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Delete<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Delete, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP HEAD request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Head<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Head, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP OPTION request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Options<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(HttpMethod.Options, path, options, config), config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTP PATCH request (synchronous).
|
||||
/// </summary>
|
||||
/// <param name="path">The target path (or resource).</param>
|
||||
/// <param name="options">The additional request options.</param>
|
||||
/// <param name="configuration">A per-request configuration object. It is assumed that any merge with
|
||||
/// GlobalConfiguration has been done before calling this method.</param>
|
||||
/// <returns>A Task containing ApiResponse</returns>
|
||||
public ApiResponse<T> Patch<T>(string path, RequestOptions options, IReadableConfiguration configuration = null)
|
||||
{
|
||||
var config = configuration ?? GlobalConfiguration.Instance;
|
||||
return Exec<T>(NewRequest(new HttpMethod("PATCH"), path, options, config), config);
|
||||
}
|
||||
#endregion ISynchronousClient
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Represents a File passed to the API as a Parameter, allows using different backends for files
|
||||
/// </summary>
|
||||
public class FileParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The filename
|
||||
/// </summary>
|
||||
public string Name { get; set; } = "no_name_provided";
|
||||
|
||||
/// <summary>
|
||||
/// The content of the file
|
||||
/// </summary>
|
||||
public Stream Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Construct a FileParameter just from the contents, will extract the filename from a filestream
|
||||
/// </summary>
|
||||
/// <param name="content"> The file content </param>
|
||||
public FileParameter(Stream content)
|
||||
{
|
||||
if (content is FileStream fs)
|
||||
{
|
||||
Name = fs.Name;
|
||||
}
|
||||
Content = content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a FileParameter from name and content
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename</param>
|
||||
/// <param name="content">The file content</param>
|
||||
public FileParameter(string filename, Stream content)
|
||||
{
|
||||
Name = filename;
|
||||
Content = content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicit conversion of stream to file parameter. Useful for backwards compatibility.
|
||||
/// </summary>
|
||||
/// <param name="s">Stream to convert</param>
|
||||
/// <returns>FileParameter</returns>
|
||||
public static implicit operator FileParameter(Stream s) => new FileParameter(s);
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
||||
namespace {{packageName}}.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// A container for generalized request inputs. This type allows consumers to extend the request functionality
|
||||
/// by abstracting away from the default (built-in) request framework (e.g. RestSharp).
|
||||
/// </summary>
|
||||
public class RequestOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters to be bound to path parts of the Request's URL
|
||||
/// </summary>
|
||||
public Dictionary<string, string> PathParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Query parameters to be applied to the request.
|
||||
/// Keys may have 1 or more values associated.
|
||||
/// </summary>
|
||||
public Multimap<string, string> QueryParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Header parameters to be applied to to the request.
|
||||
/// Keys may have 1 or more values associated.
|
||||
/// </summary>
|
||||
public Multimap<string, string> HeaderParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Form parameters to be sent along with the request.
|
||||
/// </summary>
|
||||
public Dictionary<string, string> FormParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File parameters to be sent along with the request.
|
||||
/// </summary>
|
||||
public Dictionary<string, FileParameter> FileParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cookies to be sent along with the request.
|
||||
/// </summary>
|
||||
public List<Cookie> Cookies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Any data associated with a request body.
|
||||
/// </summary>
|
||||
public Object Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of <see cref="RequestOptions"/>
|
||||
/// </summary>
|
||||
public RequestOptions()
|
||||
{
|
||||
PathParameters = new Dictionary<string, string>();
|
||||
QueryParameters = new Multimap<string, string>();
|
||||
HeaderParameters = new Multimap<string, string>();
|
||||
FormParameters = new Dictionary<string, string>();
|
||||
FileParameters = new Dictionary<string, FileParameter>();
|
||||
Cookies = new List<Cookie>();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,724 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Mime;
|
||||
using {{packageName}}.Client;
|
||||
{{#hasImport}}using {{packageName}}.{{modelPackage}};
|
||||
{{/hasImport}}
|
||||
|
||||
namespace {{packageName}}.{{apiPackage}}
|
||||
{
|
||||
{{#operations}}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of functions to interact with the API endpoints
|
||||
/// </summary>
|
||||
{{>visibility}} interface {{interfacePrefix}}{{classname}}Sync : IApiAccessor
|
||||
{
|
||||
#region Synchronous Operations
|
||||
{{#operation}}
|
||||
/// <summary>
|
||||
/// {{summary}}
|
||||
/// </summary>
|
||||
{{#notes}}
|
||||
/// <remarks>
|
||||
/// {{notes}}
|
||||
/// </remarks>
|
||||
{{/notes}}
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}/// <returns>{{#returnType}}{{returnType}}{{/returnType}}</returns>
|
||||
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}}
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// {{notes}}
|
||||
/// </remarks>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}/// <returns>ApiResponse of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object(void){{/returnType}}</returns>
|
||||
ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
{{/operation}}
|
||||
#endregion Synchronous Operations
|
||||
}
|
||||
|
||||
{{#supportsAsync}}
|
||||
/// <summary>
|
||||
/// Represents a collection of functions to interact with the API endpoints
|
||||
/// </summary>
|
||||
{{>visibility}} interface {{interfacePrefix}}{{classname}}Async : IApiAccessor
|
||||
{
|
||||
#region Asynchronous Operations
|
||||
{{#operation}}
|
||||
/// <summary>
|
||||
/// {{summary}}
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// {{notes}}
|
||||
/// </remarks>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}
|
||||
/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <returns>Task of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}</returns>
|
||||
{{#returnType}}System.Threading.Tasks.Task<{{{returnType}}}>{{/returnType}}{{^returnType}}System.Threading.Tasks.Task{{/returnType}} {{operationId}}Async({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}}
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// {{notes}}
|
||||
/// </remarks>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}
|
||||
/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <returns>Task of ApiResponse{{#returnType}} ({{returnType}}){{/returnType}}</returns>
|
||||
System.Threading.Tasks.Task<ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>> {{operationId}}WithHttpInfoAsync({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
{{/operation}}
|
||||
#endregion Asynchronous Operations
|
||||
}
|
||||
{{/supportsAsync}}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of functions to interact with the API endpoints
|
||||
/// </summary>
|
||||
{{>visibility}} interface {{interfacePrefix}}{{classname}} : {{interfacePrefix}}{{classname}}Sync{{#supportsAsync}}, {{interfacePrefix}}{{classname}}Async{{/supportsAsync}}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of functions to interact with the API endpoints
|
||||
/// </summary>
|
||||
{{>visibility}} partial class {{classname}} : IDisposable, {{interfacePrefix}}{{classname}}
|
||||
{
|
||||
private {{packageName}}.Client.ExceptionFactory _exceptionFactory = (name, response) => null;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
|
||||
/// **IMPORTANT** This will also create an istance of HttpClient, which is less than ideal.
|
||||
/// It's better to reuse the <see href="https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests#issues-with-the-original-httpclient-class-available-in-net">HttpClient and HttpClientHander</see>.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public {{classname}}() : this((string)null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
|
||||
/// **IMPORTANT** This will also create an istance of HttpClient, which is less than ideal.
|
||||
/// It's better to reuse the <see href="https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests#issues-with-the-original-httpclient-class-available-in-net">HttpClient and HttpClientHander</see>.
|
||||
/// </summary>
|
||||
/// <param name="basePath">The target service's base path in URL format.</param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
/// <returns></returns>
|
||||
public {{classname}}(string basePath)
|
||||
{
|
||||
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
|
||||
{{packageName}}.Client.GlobalConfiguration.Instance,
|
||||
new {{packageName}}.Client.Configuration { BasePath = basePath }
|
||||
);
|
||||
this.ApiClient = new {{packageName}}.Client.ApiClient(this.Configuration.BasePath);
|
||||
this.Client = this.ApiClient;
|
||||
{{#supportsAsync}}
|
||||
this.AsynchronousClient = this.ApiClient;
|
||||
{{/supportsAsync}}
|
||||
this.ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class using Configuration object.
|
||||
/// **IMPORTANT** This will also create an istance of HttpClient, which is less than ideal.
|
||||
/// It's better to reuse the <see href="https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests#issues-with-the-original-httpclient-class-available-in-net">HttpClient and HttpClientHander</see>.
|
||||
/// </summary>
|
||||
/// <param name="configuration">An instance of Configuration.</param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <returns></returns>
|
||||
public {{classname}}({{packageName}}.Client.Configuration configuration)
|
||||
{
|
||||
if (configuration == null) throw new ArgumentNullException("configuration");
|
||||
|
||||
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
|
||||
{{packageName}}.Client.GlobalConfiguration.Instance,
|
||||
configuration
|
||||
);
|
||||
this.ApiClient = new {{packageName}}.Client.ApiClient(this.Configuration.BasePath);
|
||||
this.Client = this.ApiClient;
|
||||
{{#supportsAsync}}
|
||||
this.AsynchronousClient = this.ApiClient;
|
||||
{{/supportsAsync}}
|
||||
ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="client">An instance of HttpClient.</param>
|
||||
/// <param name="handler">An optional instance of HttpClientHandler that is used by HttpClient.</param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Some configuration settings will not be applied without passing an HttpClientHandler.
|
||||
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
|
||||
/// </remarks>
|
||||
public {{classname}}(HttpClient client, HttpClientHandler handler = null) : this(client, (string)null, handler)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="client">An instance of HttpClient.</param>
|
||||
/// <param name="basePath">The target service's base path in URL format.</param>
|
||||
/// <param name="handler">An optional instance of HttpClientHandler that is used by HttpClient.</param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Some configuration settings will not be applied without passing an HttpClientHandler.
|
||||
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
|
||||
/// </remarks>
|
||||
public {{classname}}(HttpClient client, string basePath, HttpClientHandler handler = null)
|
||||
{
|
||||
if (client == null) throw new ArgumentNullException("client");
|
||||
|
||||
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
|
||||
{{packageName}}.Client.GlobalConfiguration.Instance,
|
||||
new {{packageName}}.Client.Configuration { BasePath = basePath }
|
||||
);
|
||||
this.ApiClient = new {{packageName}}.Client.ApiClient(client, this.Configuration.BasePath, handler);
|
||||
this.Client = this.ApiClient;
|
||||
{{#supportsAsync}}
|
||||
this.AsynchronousClient = this.ApiClient;
|
||||
{{/supportsAsync}}
|
||||
this.ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class using Configuration object.
|
||||
/// </summary>
|
||||
/// <param name="client">An instance of HttpClient.</param>
|
||||
/// <param name="configuration">An instance of Configuration.</param>
|
||||
/// <param name="handler">An optional instance of HttpClientHandler that is used by HttpClient.</param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Some configuration settings will not be applied without passing an HttpClientHandler.
|
||||
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
|
||||
/// </remarks>
|
||||
public {{classname}}(HttpClient client, {{packageName}}.Client.Configuration configuration, HttpClientHandler handler = null)
|
||||
{
|
||||
if (configuration == null) throw new ArgumentNullException("configuration");
|
||||
if (client == null) throw new ArgumentNullException("client");
|
||||
|
||||
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
|
||||
{{packageName}}.Client.GlobalConfiguration.Instance,
|
||||
configuration
|
||||
);
|
||||
this.ApiClient = new {{packageName}}.Client.ApiClient(client, this.Configuration.BasePath, handler);
|
||||
this.Client = this.ApiClient;
|
||||
{{#supportsAsync}}
|
||||
this.AsynchronousClient = this.ApiClient;
|
||||
{{/supportsAsync}}
|
||||
ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}"/> class
|
||||
/// using a Configuration object and client instance.
|
||||
/// </summary>
|
||||
/// <param name="client">The client interface for synchronous API access.</param>{{#supportsAsync}}
|
||||
/// <param name="asyncClient">The client interface for asynchronous API access.</param>{{/supportsAsync}}
|
||||
/// <param name="configuration">The configuration object.</param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public {{classname}}({{packageName}}.Client.ISynchronousClient client, {{#supportsAsync}}{{packageName}}.Client.IAsynchronousClient asyncClient, {{/supportsAsync}}{{packageName}}.Client.IReadableConfiguration configuration)
|
||||
{
|
||||
if (client == null) throw new ArgumentNullException("client");
|
||||
{{#supportsAsync}}
|
||||
if (asyncClient == null) throw new ArgumentNullException("asyncClient");
|
||||
{{/supportsAsync}}
|
||||
if (configuration == null) throw new ArgumentNullException("configuration");
|
||||
|
||||
this.Client = client;
|
||||
{{#supportsAsync}}
|
||||
this.AsynchronousClient = asyncClient;
|
||||
{{/supportsAsync}}
|
||||
this.Configuration = configuration;
|
||||
this.ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes resources if they were created by us
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.ApiClient?.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the ApiClient if created
|
||||
/// </summary>
|
||||
public {{packageName}}.Client.ApiClient ApiClient { get; set; } = null;
|
||||
|
||||
{{#supportsAsync}}
|
||||
/// <summary>
|
||||
/// The client for accessing this underlying API asynchronously.
|
||||
/// </summary>
|
||||
public {{packageName}}.Client.IAsynchronousClient AsynchronousClient { get; set; }
|
||||
{{/supportsAsync}}
|
||||
|
||||
/// <summary>
|
||||
/// The client for accessing this underlying API synchronously.
|
||||
/// </summary>
|
||||
public {{packageName}}.Client.ISynchronousClient Client { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base path of the API client.
|
||||
/// </summary>
|
||||
/// <value>The base path</value>
|
||||
public string GetBasePath()
|
||||
{
|
||||
return this.Configuration.BasePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration object
|
||||
/// </summary>
|
||||
/// <value>An instance of the Configuration</value>
|
||||
public {{packageName}}.Client.IReadableConfiguration Configuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Provides a factory method hook for the creation of exceptions.
|
||||
/// </summary>
|
||||
public {{packageName}}.Client.ExceptionFactory ExceptionFactory
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_exceptionFactory != null && _exceptionFactory.GetInvocationList().Length > 1)
|
||||
{
|
||||
throw new InvalidOperationException("Multicast delegate for ExceptionFactory is unsupported.");
|
||||
}
|
||||
return _exceptionFactory;
|
||||
}
|
||||
set { _exceptionFactory = value; }
|
||||
}
|
||||
|
||||
{{#operation}}
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}/// <returns>{{#returnType}}{{returnType}}{{/returnType}}</returns>
|
||||
public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||
{
|
||||
{{#returnType}}{{packageName}}.Client.ApiResponse<{{{returnType}}}> localVarResponse = {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
|
||||
return localVarResponse.Data;{{/returnType}}{{^returnType}}{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});{{/returnType}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}/// <returns>ApiResponse of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object(void){{/returnType}}</returns>
|
||||
public {{packageName}}.Client.ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||
{
|
||||
{{#allParams}}
|
||||
{{#required}}
|
||||
{{^vendorExtensions.x-csharp-value-type}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null)
|
||||
throw new {{packageName}}.Client.ApiException(400, "Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}");
|
||||
|
||||
{{/vendorExtensions.x-csharp-value-type}}
|
||||
{{/required}}
|
||||
{{/allParams}}
|
||||
{{packageName}}.Client.RequestOptions localVarRequestOptions = new {{packageName}}.Client.RequestOptions();
|
||||
|
||||
string[] _contentTypes = new string[] {
|
||||
{{#consumes}}
|
||||
"{{{mediaType}}}"{{^-last}},{{/-last}}
|
||||
{{/consumes}}
|
||||
};
|
||||
|
||||
// to determine the Accept header
|
||||
string[] _accepts = new string[] {
|
||||
{{#produces}}
|
||||
"{{{mediaType}}}"{{^-last}},{{/-last}}
|
||||
{{/produces}}
|
||||
};
|
||||
|
||||
var localVarContentType = {{packageName}}.Client.ClientUtils.SelectHeaderContentType(_contentTypes);
|
||||
if (localVarContentType != null) localVarRequestOptions.HeaderParameters.Add("Content-Type", localVarContentType);
|
||||
|
||||
var localVarAccept = {{packageName}}.Client.ClientUtils.SelectHeaderAccept(_accepts);
|
||||
if (localVarAccept != null) localVarRequestOptions.HeaderParameters.Add("Accept", localVarAccept);
|
||||
|
||||
{{#pathParams}}
|
||||
{{#required}}
|
||||
localVarRequestOptions.PathParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // path parameter
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
localVarRequestOptions.PathParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // path parameter
|
||||
}
|
||||
{{/required}}
|
||||
{{/pathParams}}
|
||||
{{#queryParams}}
|
||||
{{#required}}
|
||||
{{#isDeepObject}}
|
||||
{{#items.vars}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}.{{name}}));
|
||||
{{/items.vars}}
|
||||
{{^items}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("deepObject", "{{baseName}}", {{paramName}}));
|
||||
{{/items}}
|
||||
{{/isDeepObject}}
|
||||
{{^isDeepObject}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
|
||||
{{/isDeepObject}}
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
{{#isDeepObject}}
|
||||
{{#items.vars}}
|
||||
if ({{paramName}}.{{name}} != null)
|
||||
{
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}.{{name}}));
|
||||
}
|
||||
{{/items.vars}}
|
||||
{{^items}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("deepObject", "{{baseName}}", {{paramName}}));
|
||||
{{/items}}
|
||||
{{/isDeepObject}}
|
||||
{{^isDeepObject}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
|
||||
{{/isDeepObject}}
|
||||
}
|
||||
{{/required}}
|
||||
{{/queryParams}}
|
||||
{{#headerParams}}
|
||||
{{#required}}
|
||||
localVarRequestOptions.HeaderParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // header parameter
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // header parameter
|
||||
}
|
||||
{{/required}}
|
||||
{{/headerParams}}
|
||||
{{#formParams}}
|
||||
{{#required}}
|
||||
{{#isFile}}
|
||||
localVarRequestOptions.FileParameters.Add("{{baseName}}", {{paramName}});
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
localVarRequestOptions.FormParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // form parameter
|
||||
{{/isFile}}
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
{{#isFile}}
|
||||
localVarRequestOptions.FileParameters.Add("{{baseName}}", {{paramName}});
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
localVarRequestOptions.FormParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // form parameter
|
||||
{{/isFile}}
|
||||
}
|
||||
{{/required}}
|
||||
{{/formParams}}
|
||||
{{#bodyParam}}
|
||||
localVarRequestOptions.Data = {{paramName}};
|
||||
{{/bodyParam}}
|
||||
|
||||
{{#authMethods}}
|
||||
// authentication ({{name}}) required
|
||||
{{#isApiKey}}
|
||||
{{#isKeyInCookie}}
|
||||
// cookie parameter support
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.Cookies.Add(new Cookie("{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")));
|
||||
}
|
||||
{{/isKeyInCookie}}
|
||||
{{#isKeyInHeader}}
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}"));
|
||||
}
|
||||
{{/isKeyInHeader}}
|
||||
{{#isKeyInQuery}}
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("", "{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")));
|
||||
}
|
||||
{{/isKeyInQuery}}
|
||||
{{/isApiKey}}
|
||||
{{#isBasicBasic}}
|
||||
// http basic authentication required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.Username) || !string.IsNullOrEmpty(this.Configuration.Password))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Basic " + {{packageName}}.Client.ClientUtils.Base64Encode(this.Configuration.Username + ":" + this.Configuration.Password));
|
||||
}
|
||||
{{/isBasicBasic}}
|
||||
{{#isBasicBearer}}
|
||||
// bearer authentication required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.AccessToken))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Bearer " + this.Configuration.AccessToken);
|
||||
}
|
||||
{{/isBasicBearer}}
|
||||
{{#isOAuth}}
|
||||
// oauth required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.AccessToken))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Bearer " + this.Configuration.AccessToken);
|
||||
}
|
||||
{{/isOAuth}}
|
||||
{{#isHttpSignature}}
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "{{{httpMethod}}}", "{{{path}}}", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters[headerItem.Key] = new List<string>() { headerItem.Value };
|
||||
}
|
||||
else
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add(headerItem.Key, headerItem.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
{{/isHttpSignature}}
|
||||
{{/authMethods}}
|
||||
|
||||
// make the HTTP request
|
||||
var localVarResponse = this.Client.{{#lambda.titlecase}}{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}{{/lambda.titlecase}}<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>("{{{path}}}", localVarRequestOptions, this.Configuration);
|
||||
|
||||
if (this.ExceptionFactory != null)
|
||||
{
|
||||
Exception _exception = this.ExceptionFactory("{{operationId}}", localVarResponse);
|
||||
if (_exception != null) throw _exception;
|
||||
}
|
||||
|
||||
return localVarResponse;
|
||||
}
|
||||
|
||||
{{#supportsAsync}}
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}
|
||||
/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <returns>Task of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}</returns>
|
||||
{{#returnType}}public async System.Threading.Tasks.Task<{{{returnType}}}>{{/returnType}}{{^returnType}}public async System.Threading.Tasks.Task{{/returnType}} {{operationId}}Async({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
{{#returnType}}{{packageName}}.Client.ApiResponse<{{{returnType}}}> localVarResponse = await {{operationId}}WithHttpInfoAsync({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}cancellationToken).ConfigureAwait(false);
|
||||
return localVarResponse.Data;{{/returnType}}{{^returnType}}await {{operationId}}WithHttpInfoAsync({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}cancellationToken).ConfigureAwait(false);{{/returnType}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {{summary}} {{notes}}
|
||||
/// </summary>
|
||||
/// <exception cref="{{packageName}}.Client.ApiException">Thrown when fails to make API call</exception>
|
||||
{{#allParams}}
|
||||
/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
|
||||
{{/allParams}}
|
||||
/// <param name="cancellationToken">Cancellation Token to cancel the request.</param>
|
||||
/// <returns>Task of ApiResponse{{#returnType}} ({{returnType}}){{/returnType}}</returns>
|
||||
public async System.Threading.Tasks.Task<{{packageName}}.Client.ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>> {{operationId}}WithHttpInfoAsync({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#allParams.0}}, {{/allParams.0}}System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
|
||||
{
|
||||
{{#allParams}}
|
||||
{{#required}}
|
||||
{{^vendorExtensions.x-csharp-value-type}}
|
||||
// verify the required parameter '{{paramName}}' is set
|
||||
if ({{paramName}} == null)
|
||||
throw new {{packageName}}.Client.ApiException(400, "Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}");
|
||||
|
||||
{{/vendorExtensions.x-csharp-value-type}}
|
||||
{{/required}}
|
||||
{{/allParams}}
|
||||
|
||||
{{packageName}}.Client.RequestOptions localVarRequestOptions = new {{packageName}}.Client.RequestOptions();
|
||||
|
||||
string[] _contentTypes = new string[] {
|
||||
{{#consumes}}
|
||||
"{{{mediaType}}}"{{^-last}}, {{/-last}}
|
||||
{{/consumes}}
|
||||
};
|
||||
|
||||
// to determine the Accept header
|
||||
string[] _accepts = new string[] {
|
||||
{{#produces}}
|
||||
"{{{mediaType}}}"{{^-last}},{{/-last}}
|
||||
{{/produces}}
|
||||
};
|
||||
|
||||
|
||||
var localVarContentType = {{packageName}}.Client.ClientUtils.SelectHeaderContentType(_contentTypes);
|
||||
if (localVarContentType != null) localVarRequestOptions.HeaderParameters.Add("Content-Type", localVarContentType);
|
||||
|
||||
var localVarAccept = {{packageName}}.Client.ClientUtils.SelectHeaderAccept(_accepts);
|
||||
if (localVarAccept != null) localVarRequestOptions.HeaderParameters.Add("Accept", localVarAccept);
|
||||
|
||||
{{#pathParams}}
|
||||
{{#required}}
|
||||
localVarRequestOptions.PathParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // path parameter
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
localVarRequestOptions.PathParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // path parameter
|
||||
}
|
||||
{{/required}}
|
||||
{{/pathParams}}
|
||||
{{#queryParams}}
|
||||
{{#required}}
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
|
||||
}
|
||||
{{/required}}
|
||||
{{/queryParams}}
|
||||
{{#headerParams}}
|
||||
{{#required}}
|
||||
localVarRequestOptions.HeaderParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // header parameter
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // header parameter
|
||||
}
|
||||
{{/required}}
|
||||
{{/headerParams}}
|
||||
{{#formParams}}
|
||||
{{#required}}
|
||||
{{#isFile}}
|
||||
localVarRequestOptions.FileParameters.Add("{{baseName}}", {{paramName}});
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
localVarRequestOptions.FormParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // form parameter
|
||||
{{/isFile}}
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{paramName}} != null)
|
||||
{
|
||||
{{#isFile}}
|
||||
localVarRequestOptions.FileParameters.Add("{{baseName}}", {{paramName}});
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
localVarRequestOptions.FormParameters.Add("{{baseName}}", {{packageName}}.Client.ClientUtils.ParameterToString({{paramName}})); // form parameter
|
||||
{{/isFile}}
|
||||
}
|
||||
{{/required}}
|
||||
{{/formParams}}
|
||||
{{#bodyParam}}
|
||||
localVarRequestOptions.Data = {{paramName}};
|
||||
{{/bodyParam}}
|
||||
|
||||
{{#authMethods}}
|
||||
// authentication ({{name}}) required
|
||||
{{#isApiKey}}
|
||||
{{#isKeyInCookie}}
|
||||
// cookie parameter support
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.Cookies.Add(new Cookie("{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")));
|
||||
}
|
||||
{{/isKeyInCookie}}
|
||||
{{#isKeyInHeader}}
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}"));
|
||||
}
|
||||
{{/isKeyInHeader}}
|
||||
{{#isKeyInQuery}}
|
||||
if (!string.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")))
|
||||
{
|
||||
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("", "{{keyParamName}}", this.Configuration.GetApiKeyWithPrefix("{{keyParamName}}")));
|
||||
}
|
||||
{{/isKeyInQuery}}
|
||||
{{/isApiKey}}
|
||||
{{#isBasic}}
|
||||
{{#isBasicBasic}}
|
||||
// http basic authentication required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.Username) || !string.IsNullOrEmpty(this.Configuration.Password))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Basic " + {{packageName}}.Client.ClientUtils.Base64Encode(this.Configuration.Username + ":" + this.Configuration.Password));
|
||||
}
|
||||
{{/isBasicBasic}}
|
||||
{{#isBasicBearer}}
|
||||
// bearer authentication required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.AccessToken))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Bearer " + this.Configuration.AccessToken);
|
||||
}
|
||||
{{/isBasicBearer}}
|
||||
{{/isBasic}}
|
||||
{{#isOAuth}}
|
||||
// oauth required
|
||||
if (!string.IsNullOrEmpty(this.Configuration.AccessToken))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add("Authorization", "Bearer " + this.Configuration.AccessToken);
|
||||
}
|
||||
{{/isOAuth}}
|
||||
{{#isHttpSignature}}
|
||||
if (this.Configuration.HttpSigningConfiguration != null)
|
||||
{
|
||||
var HttpSigningHeaders = this.Configuration.HttpSigningConfiguration.GetHttpSignedHeader(this.Configuration.BasePath, "{{{httpMethod}}}", "{{{path}}}", localVarRequestOptions);
|
||||
foreach (var headerItem in HttpSigningHeaders)
|
||||
{
|
||||
if (localVarRequestOptions.HeaderParameters.ContainsKey(headerItem.Key))
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters[headerItem.Key] = new List<string>() { headerItem.Value };
|
||||
}
|
||||
else
|
||||
{
|
||||
localVarRequestOptions.HeaderParameters.Add(headerItem.Key, headerItem.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
{{/isHttpSignature}}
|
||||
{{/authMethods}}
|
||||
|
||||
// make the HTTP request
|
||||
|
||||
var localVarResponse = await this.AsynchronousClient.{{#lambda.titlecase}}{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}{{/lambda.titlecase}}Async<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>("{{{path}}}", localVarRequestOptions, this.Configuration, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (this.ExceptionFactory != null)
|
||||
{
|
||||
Exception _exception = this.ExceptionFactory("{{operationId}}", localVarResponse);
|
||||
if (_exception != null) throw _exception;
|
||||
}
|
||||
|
||||
return localVarResponse;
|
||||
}
|
||||
|
||||
{{/supportsAsync}}
|
||||
{{/operation}}
|
||||
}
|
||||
{{/operations}}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#discriminator}}
|
||||
using JsonSubTypes;
|
||||
{{/discriminator}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
{{#validatable}}
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
{{/validatable}}
|
||||
using FileParameter = {{packageName}}.Client.FileParameter;
|
||||
using OpenAPIDateConverter = {{packageName}}.Client.OpenAPIDateConverter;
|
||||
{{#useCompareNetObjects}}
|
||||
using OpenAPIClientUtils = {{packageName}}.Client.ClientUtils;
|
||||
{{/useCompareNetObjects}}
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#oneOf}}
|
||||
{{#-first}}
|
||||
using System.Reflection;
|
||||
{{/-first}}
|
||||
{{/oneOf}}
|
||||
{{#aneOf}}
|
||||
{{#-first}}
|
||||
using System.Reflection;
|
||||
{{/-first}}
|
||||
{{/aneOf}}
|
||||
|
||||
namespace {{packageName}}.{{modelPackage}}
|
||||
{
|
||||
{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}}{{#anyOf}}{{#-first}}{{>modelAnyOf}}{{/-first}}{{/anyOf}}{{^oneOf}}{{^anyOf}}{{>modelGeneric}}{{/anyOf}}{{/oneOf}}{{/isEnum}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
}
|
47
modules/openapi-generator/src/main/resources/csharp-netcore-functions/model.mustache
vendored
Normal file
47
modules/openapi-generator/src/main/resources/csharp-netcore-functions/model.mustache
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#discriminator}}
|
||||
using JsonSubTypes;
|
||||
{{/discriminator}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
{{#validatable}}
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
{{/validatable}}
|
||||
using OpenAPIDateConverter = {{packageName}}.Client.OpenAPIDateConverter;
|
||||
{{#useCompareNetObjects}}
|
||||
using OpenAPIClientUtils = {{packageName}}.Client.ClientUtils;
|
||||
{{/useCompareNetObjects}}
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#oneOf}}
|
||||
{{#-first}}
|
||||
using System.Reflection;
|
||||
{{/-first}}
|
||||
{{/oneOf}}
|
||||
{{#aneOf}}
|
||||
{{#-first}}
|
||||
using System.Reflection;
|
||||
{{/-first}}
|
||||
{{/aneOf}}
|
||||
|
||||
namespace {{packageName}}.{{modelPackage}}
|
||||
{
|
||||
{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}}{{#anyOf}}{{#-first}}{{>modelAnyOf}}{{/-first}}{{/anyOf}}{{^oneOf}}{{^anyOf}}{{>modelGeneric}}{{/anyOf}}{{/oneOf}}{{/isEnum}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
}
|
227
modules/openapi-generator/src/main/resources/csharp-netcore-functions/modelAnyOf.mustache
vendored
Normal file
227
modules/openapi-generator/src/main/resources/csharp-netcore-functions/modelAnyOf.mustache
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
/// <summary>
|
||||
/// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}}
|
||||
/// </summary>
|
||||
[JsonConverter(typeof({{classname}}JsonConverter))]
|
||||
[DataContract(Name = "{{{name}}}")]
|
||||
{{>visibility}} partial class {{classname}} : AbstractOpenAPISchema, {{#parent}}{{{parent}}}, {{/parent}}IEquatable<{{classname}}>{{#validatable}}, IValidatableObject{{/validatable}}
|
||||
{
|
||||
{{#isNullable}}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}" /> class.
|
||||
/// </summary>
|
||||
public {{classname}}()
|
||||
{
|
||||
this.IsNullable = true;
|
||||
this.SchemaType= "anyOf";
|
||||
}
|
||||
|
||||
{{/isNullable}}
|
||||
{{#anyOf}}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}" /> class
|
||||
/// with the <see cref="{{{.}}}" /> class
|
||||
/// </summary>
|
||||
/// <param name="actualInstance">An instance of {{{.}}}.</param>
|
||||
public {{classname}}({{{.}}} actualInstance)
|
||||
{
|
||||
this.IsNullable = {{#isNullable}}true{{/isNullable}}{{^isNullable}}false{{/isNullable}};
|
||||
this.SchemaType= "anyOf";
|
||||
this.ActualInstance = actualInstance{{^isNullable}} ?? throw new ArgumentException("Invalid instance found. Must not be null."){{/isNullable}};
|
||||
}
|
||||
|
||||
{{/anyOf}}
|
||||
|
||||
private Object _actualInstance;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets ActualInstance
|
||||
/// </summary>
|
||||
public override Object ActualInstance
|
||||
{
|
||||
get
|
||||
{
|
||||
return _actualInstance;
|
||||
}
|
||||
set
|
||||
{
|
||||
{{#anyOf}}
|
||||
{{^-first}}else {{/-first}}if (value.GetType() == typeof({{{.}}}))
|
||||
{
|
||||
this._actualInstance = value;
|
||||
}
|
||||
{{/anyOf}}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Invalid instance found. Must be the following types:{{#anyOf}} {{{.}}}{{^-last}},{{/-last}}{{/anyOf}}");
|
||||
}
|
||||
}
|
||||
}
|
||||
{{#anyOf}}
|
||||
|
||||
/// <summary>
|
||||
/// Get the actual instance of `{{{.}}}`. If the actual instanct is not `{{{.}}}`,
|
||||
/// the InvalidClassException will be thrown
|
||||
/// </summary>
|
||||
/// <returns>An instance of {{{.}}}</returns>
|
||||
public {{{.}}} Get{{{.}}}()
|
||||
{
|
||||
return ({{{.}}})this.ActualInstance;
|
||||
}
|
||||
{{/anyOf}}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the string presentation of the object
|
||||
/// </summary>
|
||||
/// <returns>String presentation of the object</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("class {{classname}} {\n");
|
||||
sb.Append(" ActualInstance: ").Append(this.ActualInstance).Append("\n");
|
||||
sb.Append("}\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the JSON string presentation of the object
|
||||
/// </summary>
|
||||
/// <returns>JSON string presentation of the object</returns>
|
||||
public override string ToJson()
|
||||
{
|
||||
return JsonConvert.SerializeObject(this.ActualInstance, {{classname}}.SerializerSettings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the JSON string into an instance of {{classname}}
|
||||
/// </summary>
|
||||
/// <param name="jsonString">JSON string</param>
|
||||
/// <returns>An instance of {{classname}}</returns>
|
||||
public static {{classname}} FromJson(string jsonString)
|
||||
{
|
||||
{{classname}} new{{classname}} = null;
|
||||
|
||||
if (jsonString == null)
|
||||
{
|
||||
return new{{classname}};
|
||||
}
|
||||
{{#anyOf}}
|
||||
|
||||
try
|
||||
{
|
||||
new{{classname}} = new {{classname}}(JsonConvert.DeserializeObject<{{{.}}}>(jsonString, {{classname}}.SerializerSettings));
|
||||
// deserialization is considered successful at this point if no exception has been thrown.
|
||||
return new{{classname}};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// deserialization failed, try the next one
|
||||
System.Diagnostics.Debug.WriteLine(string.Format("Failed to deserialize `{0}` into {{{.}}}: {1}", jsonString, exception.ToString()));
|
||||
}
|
||||
{{/anyOf}}
|
||||
|
||||
// no match found, throw an exception
|
||||
throw new InvalidDataException("The JSON string `" + jsonString + "` cannot be deserialized into any schema defined.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if objects are equal
|
||||
/// </summary>
|
||||
/// <param name="input">Object to be compared</param>
|
||||
/// <returns>Boolean</returns>
|
||||
public override bool Equals(object input)
|
||||
{
|
||||
{{#useCompareNetObjects}}
|
||||
return OpenAPIClientUtils.compareLogic.Compare(this, input as {{classname}}).AreEqual;
|
||||
{{/useCompareNetObjects}}
|
||||
{{^useCompareNetObjects}}
|
||||
return this.Equals(input as {{classname}});
|
||||
{{/useCompareNetObjects}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if {{classname}} instances are equal
|
||||
/// </summary>
|
||||
/// <param name="input">Instance of {{classname}} to be compared</param>
|
||||
/// <returns>Boolean</returns>
|
||||
public bool Equals({{classname}} input)
|
||||
{
|
||||
{{#useCompareNetObjects}}
|
||||
return OpenAPIClientUtils.compareLogic.Compare(this, input).AreEqual;
|
||||
{{/useCompareNetObjects}}
|
||||
{{^useCompareNetObjects}}
|
||||
if (input == null)
|
||||
return false;
|
||||
|
||||
return this.ActualInstance.Equals(input.ActualInstance);
|
||||
{{/useCompareNetObjects}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash code
|
||||
/// </summary>
|
||||
/// <returns>Hash code</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked // Overflow is fine, just wrap
|
||||
{
|
||||
int hashCode = 41;
|
||||
if (this.ActualInstance != null)
|
||||
hashCode = hashCode * 59 + this.ActualInstance.GetHashCode();
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To validate all properties of the instance
|
||||
/// </summary>
|
||||
/// <param name="validationContext">Validation context</param>
|
||||
/// <returns>Validation Result</returns>
|
||||
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Custom JSON converter for {{classname}}
|
||||
/// </summary>
|
||||
public class {{classname}}JsonConverter : JsonConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// To write the JSON string
|
||||
/// </summary>
|
||||
/// <param name="writer">JSON writer</param>
|
||||
/// <param name="value">Object to be converted into a JSON string</param>
|
||||
/// <param name="serializer">JSON Serializer</param>
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteRawValue((string)(typeof({{classname}}).GetMethod("ToJson").Invoke(value, null)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To convert a JSON string into an object
|
||||
/// </summary>
|
||||
/// <param name="reader">JSON reader</param>
|
||||
/// <param name="objectType">Object type</param>
|
||||
/// <param name="existingValue">Existing value</param>
|
||||
/// <param name="serializer">JSON Serializer</param>
|
||||
/// <returns>The object converted from the JSON string</returns>
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if(reader.TokenType != JsonToken.Null)
|
||||
{
|
||||
return {{classname}}.FromJson(JObject.Load(reader).ToString(Formatting.None));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the object can be converted
|
||||
/// </summary>
|
||||
/// <param name="objectType">Object type</param>
|
||||
/// <returns>True if the object can be converted</returns>
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
30
modules/openapi-generator/src/main/resources/csharp-netcore-functions/modelEnum.mustache
vendored
Normal file
30
modules/openapi-generator/src/main/resources/csharp-netcore-functions/modelEnum.mustache
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/// <summary>
|
||||
/// {{^description}}Defines {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
|
||||
/// </summary>
|
||||
{{#description}}
|
||||
/// <value>{{description}}</value>
|
||||
{{/description}}
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
{{#-first}}
|
||||
{{#isString}}
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
{{/isString}}
|
||||
{{/-first}}
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
{{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}{{#vendorExtensions.x-enum-byte}}: byte{{/vendorExtensions.x-enum-byte}}
|
||||
{
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
/// <summary>
|
||||
/// Enum {{name}} for value: {{{value}}}
|
||||
/// </summary>
|
||||
{{#isString}}
|
||||
[EnumMember(Value = "{{{value}}}")]
|
||||
{{/isString}}
|
||||
{{name}}{{^isString}} = {{{value}}}{{/isString}}{{#isString}} = {{-index}}{{/isString}}{{^-last}},{{/-last}}
|
||||
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
}{{! NOTE: This model's enumVars is modified to look like CodegenProperty}}
|
456
modules/openapi-generator/src/main/resources/csharp-netcore-functions/modelGeneric.mustache
vendored
Normal file
456
modules/openapi-generator/src/main/resources/csharp-netcore-functions/modelGeneric.mustache
vendored
Normal file
@ -0,0 +1,456 @@
|
||||
/// <summary>
|
||||
/// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}}
|
||||
/// </summary>
|
||||
[DataContract(Name = "{{{name}}}")]
|
||||
{{#discriminator}}
|
||||
[JsonConverter(typeof(JsonSubtypes), "{{{discriminatorName}}}")]
|
||||
{{#mappedModels}}
|
||||
[JsonSubtypes.KnownSubType(typeof({{{modelName}}}), "{{^vendorExtensions.x-discriminator-value}}{{{mappingName}}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{.}}}{{/vendorExtensions.x-discriminator-value}}")]
|
||||
{{/mappedModels}}
|
||||
{{/discriminator}}
|
||||
{{>visibility}} partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}}IEquatable<{{classname}}>{{#validatable}}, IValidatableObject{{/validatable}}
|
||||
{
|
||||
{{#vars}}
|
||||
{{#items.isEnum}}
|
||||
{{#items}}
|
||||
{{^complexType}}
|
||||
{{>modelInnerEnum}}
|
||||
{{/complexType}}
|
||||
{{/items}}
|
||||
{{/items.isEnum}}
|
||||
{{#isEnum}}
|
||||
{{^complexType}}
|
||||
{{>modelInnerEnum}}
|
||||
{{/complexType}}
|
||||
{{/isEnum}}
|
||||
{{#isEnum}}
|
||||
|
||||
/// <summary>
|
||||
/// {{^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}})]
|
||||
public {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}} {{name}} { get; set; }
|
||||
{{#isReadOnly}}
|
||||
|
||||
/// <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}}
|
||||
{{/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}}
|
||||
{{^hasOnlyReadOnly}}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}" /> class.
|
||||
/// </summary>
|
||||
[JsonConstructorAttribute]
|
||||
{{^isAdditionalPropertiesTrue}}
|
||||
protected {{classname}}() { }
|
||||
{{/isAdditionalPropertiesTrue}}
|
||||
{{#isAdditionalPropertiesTrue}}
|
||||
protected {{classname}}()
|
||||
{
|
||||
this.AdditionalProperties = new Dictionary<string, object>();
|
||||
}
|
||||
{{/isAdditionalPropertiesTrue}}
|
||||
{{/hasOnlyReadOnly}}
|
||||
{{/hasRequired}}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}" /> class.
|
||||
/// </summary>
|
||||
{{#readWriteVars}}
|
||||
/// <param name="{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}">{{#description}}{{description}}{{/description}}{{^description}}{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}{{/description}}{{#required}} (required){{/required}}{{#defaultValue}} (default to {{defaultValue}}){{/defaultValue}}.</param>
|
||||
{{/readWriteVars}}
|
||||
{{#hasOnlyReadOnly}}
|
||||
[JsonConstructorAttribute]
|
||||
{{/hasOnlyReadOnly}}
|
||||
public {{classname}}({{#readWriteVars}}{{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}}{{/isEnum}} {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} = {{#defaultValue}}{{^isDateTime}}{{{defaultValue}}}{{/isDateTime}}{{#isDateTime}}default({{{datatypeWithEnum}}}){{/isDateTime}}{{/defaultValue}}{{^defaultValue}}default({{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}}{{/isEnum}}){{/defaultValue}}{{^-last}}, {{/-last}}{{/readWriteVars}}){{#parent}} : base({{#parentVars}}{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}{{^-last}}, {{/-last}}{{/parentVars}}){{/parent}}
|
||||
{
|
||||
{{#vars}}
|
||||
{{^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}}
|
||||
{{/vars}}
|
||||
{{#vars}}
|
||||
{{^isInherited}}
|
||||
{{^isReadOnly}}
|
||||
{{^required}}
|
||||
{{#defaultValue}}
|
||||
{{^vendorExtensions.x-csharp-value-type}}
|
||||
// use default value if no "{{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}}" provided
|
||||
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}} ?? {{{defaultValue}}};
|
||||
{{/vendorExtensions.x-csharp-value-type}}
|
||||
{{#vendorExtensions.x-csharp-value-type}}
|
||||
this.{{name}} = {{#lambda.camelcase_param}}{{name}}{{/lambda.camelcase_param}};
|
||||
{{/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}}
|
||||
{{/isInherited}}
|
||||
{{/vars}}
|
||||
{{#isAdditionalPropertiesTrue}}
|
||||
this.AdditionalProperties = new Dictionary<string, object>();
|
||||
{{/isAdditionalPropertiesTrue}}
|
||||
}
|
||||
|
||||
{{#vars}}
|
||||
{{^isInherited}}
|
||||
{{^isEnum}}
|
||||
/// <summary>
|
||||
/// {{^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))]
|
||||
{{/isDate}}
|
||||
public {{{dataType}}} {{name}} { get; {{#isReadOnly}}private {{/isReadOnly}}set; }
|
||||
|
||||
{{#isReadOnly}}
|
||||
/// <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}}
|
||||
{{/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}}
|
||||
{{#isAdditionalPropertiesTrue}}
|
||||
/// <summary>
|
||||
/// Gets or Sets additional properties
|
||||
/// </summary>
|
||||
[JsonExtensionData]
|
||||
public IDictionary<string, object> AdditionalProperties { get; set; }
|
||||
|
||||
{{/isAdditionalPropertiesTrue}}
|
||||
/// <summary>
|
||||
/// Returns the string presentation of the object
|
||||
/// </summary>
|
||||
/// <returns>String presentation of the object</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("class {{classname}} {\n");
|
||||
{{#parent}}
|
||||
sb.Append(" ").Append(base.ToString().Replace("\n", "\n ")).Append("\n");
|
||||
{{/parent}}
|
||||
{{#vars}}
|
||||
sb.Append(" {{name}}: ").Append({{name}}).Append("\n");
|
||||
{{/vars}}
|
||||
{{#isAdditionalPropertiesTrue}}
|
||||
sb.Append(" AdditionalProperties: ").Append(AdditionalProperties).Append("\n");
|
||||
{{/isAdditionalPropertiesTrue}}
|
||||
sb.Append("}\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the JSON string presentation of the object
|
||||
/// </summary>
|
||||
/// <returns>JSON string presentation of the object</returns>
|
||||
public {{#parent}}{{^isArray}}{{^isMap}}override {{/isMap}}{{/isArray}}{{/parent}}{{^parent}}virtual {{/parent}}string ToJson()
|
||||
{
|
||||
return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if objects are equal
|
||||
/// </summary>
|
||||
/// <param name="input">Object to be compared</param>
|
||||
/// <returns>Boolean</returns>
|
||||
public override bool Equals(object input)
|
||||
{
|
||||
{{#useCompareNetObjects}}
|
||||
return OpenAPIClientUtils.compareLogic.Compare(this, input as {{classname}}).AreEqual;
|
||||
{{/useCompareNetObjects}}
|
||||
{{^useCompareNetObjects}}
|
||||
return this.Equals(input as {{classname}});
|
||||
{{/useCompareNetObjects}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if {{classname}} instances are equal
|
||||
/// </summary>
|
||||
/// <param name="input">Instance of {{classname}} to be compared</param>
|
||||
/// <returns>Boolean</returns>
|
||||
public bool Equals({{classname}} input)
|
||||
{
|
||||
{{#useCompareNetObjects}}
|
||||
return OpenAPIClientUtils.compareLogic.Compare(this, input).AreEqual;
|
||||
{{/useCompareNetObjects}}
|
||||
{{^useCompareNetObjects}}
|
||||
if (input == null)
|
||||
return false;
|
||||
|
||||
return {{#vars}}{{#parent}}base.Equals(input) && {{/parent}}{{^isContainer}}
|
||||
(
|
||||
this.{{name}} == input.{{name}} ||
|
||||
{{^vendorExtensions.x-is-value-type}}
|
||||
(this.{{name}} != null &&
|
||||
this.{{name}}.Equals(input.{{name}}))
|
||||
{{/vendorExtensions.x-is-value-type}}
|
||||
{{#vendorExtensions.x-is-value-type}}
|
||||
this.{{name}}.Equals(input.{{name}})
|
||||
{{/vendorExtensions.x-is-value-type}}
|
||||
){{^-last}} && {{/-last}}{{/isContainer}}{{#isContainer}}
|
||||
(
|
||||
this.{{name}} == input.{{name}} ||
|
||||
{{^vendorExtensions.x-is-value-type}}this.{{name}} != null &&
|
||||
input.{{name}} != null &&
|
||||
{{/vendorExtensions.x-is-value-type}}this.{{name}}.SequenceEqual(input.{{name}})
|
||||
){{^-last}} && {{/-last}}{{/isContainer}}{{/vars}}{{^vars}}{{#parent}}base.Equals(input){{/parent}}{{^parent}}false{{/parent}}{{/vars}}{{^isAdditionalPropertiesTrue}};{{/isAdditionalPropertiesTrue}}
|
||||
{{#isAdditionalPropertiesTrue}}
|
||||
&& (this.AdditionalProperties.Count == input.AdditionalProperties.Count && !this.AdditionalProperties.Except(input.AdditionalProperties).Any());
|
||||
{{/isAdditionalPropertiesTrue}}
|
||||
{{/useCompareNetObjects}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash code
|
||||
/// </summary>
|
||||
/// <returns>Hash code</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked // Overflow is fine, just wrap
|
||||
{
|
||||
{{#parent}}
|
||||
int hashCode = base.GetHashCode();
|
||||
{{/parent}}
|
||||
{{^parent}}
|
||||
int hashCode = 41;
|
||||
{{/parent}}
|
||||
{{#vars}}
|
||||
{{^vendorExtensions.x-is-value-type}}
|
||||
if (this.{{name}} != null)
|
||||
hashCode = hashCode * 59 + this.{{name}}.GetHashCode();
|
||||
{{/vendorExtensions.x-is-value-type}}
|
||||
{{#vendorExtensions.x-is-value-type}}
|
||||
hashCode = hashCode * 59 + this.{{name}}.GetHashCode();
|
||||
{{/vendorExtensions.x-is-value-type}}
|
||||
{{/vars}}
|
||||
{{#isAdditionalPropertiesTrue}}
|
||||
if (this.AdditionalProperties != null)
|
||||
hashCode = hashCode * 59 + this.AdditionalProperties.GetHashCode();
|
||||
{{/isAdditionalPropertiesTrue}}
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
{{#validatable}}
|
||||
{{#discriminator}}
|
||||
/// <summary>
|
||||
/// To validate all properties of the instance
|
||||
/// </summary>
|
||||
/// <param name="validationContext">Validation context</param>
|
||||
/// <returns>Validation Result</returns>
|
||||
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
|
||||
{
|
||||
return this.BaseValidate(validationContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To validate all properties of the instance
|
||||
/// </summary>
|
||||
/// <param name="validationContext">Validation context</param>
|
||||
/// <returns>Validation Result</returns>
|
||||
protected IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> BaseValidate(ValidationContext validationContext)
|
||||
{
|
||||
{{/discriminator}}
|
||||
{{^discriminator}}
|
||||
/// <summary>
|
||||
/// To validate all properties of the instance
|
||||
/// </summary>
|
||||
/// <param name="validationContext">Validation context</param>
|
||||
/// <returns>Validation Result</returns>
|
||||
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
|
||||
{
|
||||
{{/discriminator}}
|
||||
{{#parent}}
|
||||
{{^isArray}}
|
||||
{{^isMap}}
|
||||
foreach(var x in BaseValidate(validationContext)) yield return x;
|
||||
{{/isMap}}
|
||||
{{/isArray}}
|
||||
{{/parent}}
|
||||
{{#vars}}
|
||||
{{#hasValidation}}
|
||||
{{^isEnum}}
|
||||
{{#maxLength}}
|
||||
// {{{name}}} ({{{dataType}}}) maxLength
|
||||
if(this.{{{name}}} != null && this.{{{name}}}.Length > {{maxLength}})
|
||||
{
|
||||
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, length must be less than {{maxLength}}.", new [] { "{{{name}}}" });
|
||||
}
|
||||
|
||||
{{/maxLength}}
|
||||
{{#minLength}}
|
||||
// {{{name}}} ({{{dataType}}}) minLength
|
||||
if(this.{{{name}}} != null && this.{{{name}}}.Length < {{minLength}})
|
||||
{
|
||||
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, length must be greater than {{minLength}}.", new [] { "{{{name}}}" });
|
||||
}
|
||||
|
||||
{{/minLength}}
|
||||
{{#maximum}}
|
||||
// {{{name}}} ({{{dataType}}}) maximum
|
||||
if(this.{{{name}}} > ({{{dataType}}}){{maximum}})
|
||||
{
|
||||
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must be a value less than or equal to {{maximum}}.", new [] { "{{{name}}}" });
|
||||
}
|
||||
|
||||
{{/maximum}}
|
||||
{{#minimum}}
|
||||
// {{{name}}} ({{{dataType}}}) minimum
|
||||
if(this.{{{name}}} < ({{{dataType}}}){{minimum}})
|
||||
{
|
||||
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must be a value greater than or equal to {{minimum}}.", new [] { "{{{name}}}" });
|
||||
}
|
||||
|
||||
{{/minimum}}
|
||||
{{#pattern}}
|
||||
{{^isByteArray}}
|
||||
// {{{name}}} ({{{dataType}}}) pattern
|
||||
Regex regex{{{name}}} = new Regex(@"{{{vendorExtensions.x-regex}}}"{{#vendorExtensions.x-modifiers}}{{#-first}}, {{/-first}}RegexOptions.{{{.}}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}});
|
||||
if (false == regex{{{name}}}.Match(this.{{{name}}}).Success)
|
||||
{
|
||||
yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must match a pattern of " + regex{{{name}}}, new [] { "{{{name}}}" });
|
||||
}
|
||||
|
||||
{{/isByteArray}}
|
||||
{{/pattern}}
|
||||
{{/isEnum}}
|
||||
{{/hasValidation}}
|
||||
{{/vars}}
|
||||
yield break;
|
||||
}
|
||||
{{/validatable}}
|
||||
}
|
26
modules/openapi-generator/src/main/resources/csharp-netcore-functions/modelInnerEnum.mustache
vendored
Normal file
26
modules/openapi-generator/src/main/resources/csharp-netcore-functions/modelInnerEnum.mustache
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
{{^isContainer}}
|
||||
/// <summary>
|
||||
/// {{^description}}Defines {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
|
||||
/// </summary>
|
||||
{{#description}}
|
||||
/// <value>{{description}}</value>
|
||||
{{/description}}
|
||||
{{#isString}}
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
{{/isString}}
|
||||
{{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}{{#vendorExtensions.x-enum-byte}}: byte{{/vendorExtensions.x-enum-byte}}
|
||||
{
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
/// <summary>
|
||||
/// Enum {{name}} for value: {{{value}}}
|
||||
/// </summary>
|
||||
{{#isString}}
|
||||
[EnumMember(Value = "{{{value}}}")]
|
||||
{{/isString}}
|
||||
{{name}}{{^isString}} = {{{value}}}{{/isString}}{{#isString}} = {{-index}}{{/isString}}{{^-last}},{{/-last}}
|
||||
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
}
|
||||
{{/isContainer}}
|
264
modules/openapi-generator/src/main/resources/csharp-netcore-functions/modelOneOf.mustache
vendored
Normal file
264
modules/openapi-generator/src/main/resources/csharp-netcore-functions/modelOneOf.mustache
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
/// <summary>
|
||||
/// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}}
|
||||
/// </summary>
|
||||
[JsonConverter(typeof({{classname}}JsonConverter))]
|
||||
[DataContract(Name = "{{{name}}}")]
|
||||
{{>visibility}} partial class {{classname}} : AbstractOpenAPISchema, {{#parent}}{{{parent}}}, {{/parent}}IEquatable<{{classname}}>{{#validatable}}, IValidatableObject{{/validatable}}
|
||||
{
|
||||
{{#isNullable}}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}" /> class.
|
||||
/// </summary>
|
||||
public {{classname}}()
|
||||
{
|
||||
this.IsNullable = true;
|
||||
this.SchemaType= "oneOf";
|
||||
}
|
||||
|
||||
{{/isNullable}}
|
||||
{{#oneOf}}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="{{classname}}" /> class
|
||||
/// with the <see cref="{{{.}}}" /> class
|
||||
/// </summary>
|
||||
/// <param name="actualInstance">An instance of {{{.}}}.</param>
|
||||
public {{classname}}({{{.}}} actualInstance)
|
||||
{
|
||||
this.IsNullable = {{#isNullable}}true{{/isNullable}}{{^isNullable}}false{{/isNullable}};
|
||||
this.SchemaType= "oneOf";
|
||||
this.ActualInstance = actualInstance{{^isNullable}} ?? throw new ArgumentException("Invalid instance found. Must not be null."){{/isNullable}};
|
||||
}
|
||||
|
||||
{{/oneOf}}
|
||||
|
||||
private Object _actualInstance;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets ActualInstance
|
||||
/// </summary>
|
||||
public override Object ActualInstance
|
||||
{
|
||||
get
|
||||
{
|
||||
return _actualInstance;
|
||||
}
|
||||
set
|
||||
{
|
||||
{{#oneOf}}
|
||||
{{^-first}}else {{/-first}}if (value.GetType() == typeof({{{.}}}))
|
||||
{
|
||||
this._actualInstance = value;
|
||||
}
|
||||
{{/oneOf}}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Invalid instance found. Must be the following types:{{#oneOf}} {{{.}}}{{^-last}},{{/-last}}{{/oneOf}}");
|
||||
}
|
||||
}
|
||||
}
|
||||
{{#oneOf}}
|
||||
|
||||
/// <summary>
|
||||
/// Get the actual instance of `{{{.}}}`. If the actual instanct is not `{{{.}}}`,
|
||||
/// the InvalidClassException will be thrown
|
||||
/// </summary>
|
||||
/// <returns>An instance of {{{.}}}</returns>
|
||||
public {{{.}}} Get{{{.}}}()
|
||||
{
|
||||
return ({{{.}}})this.ActualInstance;
|
||||
}
|
||||
{{/oneOf}}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the string presentation of the object
|
||||
/// </summary>
|
||||
/// <returns>String presentation of the object</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("class {{classname}} {\n");
|
||||
sb.Append(" ActualInstance: ").Append(this.ActualInstance).Append("\n");
|
||||
sb.Append("}\n");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the JSON string presentation of the object
|
||||
/// </summary>
|
||||
/// <returns>JSON string presentation of the object</returns>
|
||||
public override string ToJson()
|
||||
{
|
||||
return JsonConvert.SerializeObject(this.ActualInstance, {{classname}}.SerializerSettings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the JSON string into an instance of {{classname}}
|
||||
/// </summary>
|
||||
/// <param name="jsonString">JSON string</param>
|
||||
/// <returns>An instance of {{classname}}</returns>
|
||||
public static {{classname}} FromJson(string jsonString)
|
||||
{
|
||||
{{classname}} new{{classname}} = null;
|
||||
|
||||
if (jsonString == null)
|
||||
{
|
||||
return new{{classname}};
|
||||
}
|
||||
{{#useOneOfDiscriminatorLookup}}
|
||||
{{#discriminator}}
|
||||
|
||||
string discriminatorValue = JObject.Parse(jsonString)["{{{propertyBaseName}}}"].ToString();
|
||||
switch (discriminatorValue)
|
||||
{
|
||||
{{#mappedModels}}
|
||||
case "{{{mappingName}}}":
|
||||
new{{classname}} = new {{classname}}(JsonConvert.DeserializeObject<{{{modelName}}}>(jsonString, {{classname}}.AdditionalPropertiesSerializerSettings));
|
||||
return new{{classname}};
|
||||
{{/mappedModels}}
|
||||
default:
|
||||
System.Diagnostics.Debug.WriteLine(string.Format("Failed to lookup discriminator value `{0}` for {{classname}}. Possible values:{{#mappedModels}} {{{mappingName}}}{{/mappedModels}}", discriminatorValue));
|
||||
break;
|
||||
}
|
||||
|
||||
{{/discriminator}}
|
||||
{{/useOneOfDiscriminatorLookup}}
|
||||
int match = 0;
|
||||
List<string> matchedTypes = new List<string>();
|
||||
{{#oneOf}}
|
||||
|
||||
try
|
||||
{
|
||||
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
|
||||
if (typeof({{{.}}}).GetProperty("AdditionalProperties") == null)
|
||||
{
|
||||
new{{classname}} = new {{classname}}(JsonConvert.DeserializeObject<{{{.}}}>(jsonString, {{classname}}.SerializerSettings));
|
||||
}
|
||||
else
|
||||
{
|
||||
new{{classname}} = new {{classname}}(JsonConvert.DeserializeObject<{{{.}}}>(jsonString, {{classname}}.AdditionalPropertiesSerializerSettings));
|
||||
}
|
||||
matchedTypes.Add("{{{.}}}");
|
||||
match++;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// deserialization failed, try the next one
|
||||
System.Diagnostics.Debug.WriteLine(string.Format("Failed to deserialize `{0}` into {{{.}}}: {1}", jsonString, exception.ToString()));
|
||||
}
|
||||
{{/oneOf}}
|
||||
|
||||
if (match == 0)
|
||||
{
|
||||
throw new InvalidDataException("The JSON string `" + jsonString + "` cannot be deserialized into any schema defined.");
|
||||
}
|
||||
else if (match > 1)
|
||||
{
|
||||
throw new InvalidDataException("The JSON string `" + jsonString + "` incorrectly matches more than one schema (should be exactly one match): " + matchedTypes);
|
||||
}
|
||||
|
||||
// deserialization is considered successful at this point if no exception has been thrown.
|
||||
return new{{classname}};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if objects are equal
|
||||
/// </summary>
|
||||
/// <param name="input">Object to be compared</param>
|
||||
/// <returns>Boolean</returns>
|
||||
public override bool Equals(object input)
|
||||
{
|
||||
{{#useCompareNetObjects}}
|
||||
return OpenAPIClientUtils.compareLogic.Compare(this, input as {{classname}}).AreEqual;
|
||||
{{/useCompareNetObjects}}
|
||||
{{^useCompareNetObjects}}
|
||||
return this.Equals(input as {{classname}});
|
||||
{{/useCompareNetObjects}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if {{classname}} instances are equal
|
||||
/// </summary>
|
||||
/// <param name="input">Instance of {{classname}} to be compared</param>
|
||||
/// <returns>Boolean</returns>
|
||||
public bool Equals({{classname}} input)
|
||||
{
|
||||
{{#useCompareNetObjects}}
|
||||
return OpenAPIClientUtils.compareLogic.Compare(this, input).AreEqual;
|
||||
{{/useCompareNetObjects}}
|
||||
{{^useCompareNetObjects}}
|
||||
if (input == null)
|
||||
return false;
|
||||
|
||||
return this.ActualInstance.Equals(input.ActualInstance);
|
||||
{{/useCompareNetObjects}}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash code
|
||||
/// </summary>
|
||||
/// <returns>Hash code</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked // Overflow is fine, just wrap
|
||||
{
|
||||
int hashCode = 41;
|
||||
if (this.ActualInstance != null)
|
||||
hashCode = hashCode * 59 + this.ActualInstance.GetHashCode();
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To validate all properties of the instance
|
||||
/// </summary>
|
||||
/// <param name="validationContext">Validation context</param>
|
||||
/// <returns>Validation Result</returns>
|
||||
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Custom JSON converter for {{classname}}
|
||||
/// </summary>
|
||||
public class {{classname}}JsonConverter : JsonConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// To write the JSON string
|
||||
/// </summary>
|
||||
/// <param name="writer">JSON writer</param>
|
||||
/// <param name="value">Object to be converted into a JSON string</param>
|
||||
/// <param name="serializer">JSON Serializer</param>
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteRawValue((string)(typeof({{classname}}).GetMethod("ToJson").Invoke(value, null)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To convert a JSON string into an object
|
||||
/// </summary>
|
||||
/// <param name="reader">JSON reader</param>
|
||||
/// <param name="objectType">Object type</param>
|
||||
/// <param name="existingValue">Existing value</param>
|
||||
/// <param name="serializer">JSON Serializer</param>
|
||||
/// <returns>The object converted from the JSON string</returns>
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if(reader.TokenType != JsonToken.Null)
|
||||
{
|
||||
return {{classname}}.FromJson(JObject.Load(reader).ToString(Formatting.None));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the object can be converted
|
||||
/// </summary>
|
||||
/// <param name="objectType">Object type</param>
|
||||
/// <returns>True if the object can be converted</returns>
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
22
modules/openapi-generator/src/main/resources/csharp-netcore-functions/model_doc.mustache
vendored
Normal file
22
modules/openapi-generator/src/main/resources/csharp-netcore-functions/model_doc.mustache
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
# {{{packageName}}}.{{modelPackage}}.{{{classname}}}
|
||||
{{#description}}{{&description}}
|
||||
{{/description}}
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
{{#parent}}
|
||||
{{#parentVars}}
|
||||
**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}
|
||||
{{/parentVars}}
|
||||
{{/parent}}
|
||||
{{#vars}}**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}
|
||||
{{/vars}}
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
{{/model}}
|
||||
{{/models}}
|
81
modules/openapi-generator/src/main/resources/csharp-netcore-functions/model_test.mustache
vendored
Normal file
81
modules/openapi-generator/src/main/resources/csharp-netcore-functions/model_test.mustache
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
{{>partial_header}}
|
||||
|
||||
using Xunit;
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using {{packageName}}.{{apiPackage}};
|
||||
using {{packageName}}.{{modelPackage}};
|
||||
using {{packageName}}.Client;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
namespace {{packageName}}.Test.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for testing {{classname}}
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This file is automatically generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
/// Please update the test case below to test the model.
|
||||
/// </remarks>
|
||||
public class {{classname}}Tests : IDisposable
|
||||
{
|
||||
// TODO uncomment below to declare an instance variable for {{classname}}
|
||||
//private {{classname}} instance;
|
||||
|
||||
public {{classname}}Tests()
|
||||
{
|
||||
// TODO uncomment below to create an instance of {{classname}}
|
||||
//instance = new {{classname}}();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Cleanup when everything is done.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test an instance of {{classname}}
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void {{classname}}InstanceTest()
|
||||
{
|
||||
// TODO uncomment below to test "IsType" {{classname}}
|
||||
//Assert.IsType<{{classname}}>(instance);
|
||||
}
|
||||
|
||||
{{#discriminator}}
|
||||
{{#children}}
|
||||
/// <summary>
|
||||
/// Test deserialize a {{classname}} from type {{parent}}
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void {{classname}}DeserializeFrom{{parent}}Test()
|
||||
{
|
||||
// TODO uncomment below to test deserialize a {{classname}} from type {{parent}}
|
||||
//Assert.IsType<{{parent}}>(JsonConvert.DeserializeObject<{{parent}}>(new {{classname}}().ToJson()));
|
||||
}
|
||||
{{/children}}
|
||||
{{/discriminator}}
|
||||
|
||||
{{#vars}}
|
||||
/// <summary>
|
||||
/// Test the property '{{name}}'
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void {{name}}Test()
|
||||
{
|
||||
// TODO unit test for the property '{{name}}'
|
||||
}
|
||||
{{/vars}}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
{{/model}}
|
||||
{{/models}}
|
44
modules/openapi-generator/src/main/resources/csharp-netcore-functions/netcore_project.mustache
vendored
Normal file
44
modules/openapi-generator/src/main/resources/csharp-netcore-functions/netcore_project.mustache
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<TargetFramework{{#multiTarget}}s{{/multiTarget}}>{{targetFramework}}</TargetFramework{{#multiTarget}}s{{/multiTarget}}>
|
||||
<AssemblyName>{{packageName}}</AssemblyName>
|
||||
<PackageId>{{packageName}}</PackageId>
|
||||
<OutputType>Library</OutputType>
|
||||
<Authors>{{packageAuthors}}</Authors>
|
||||
<Company>{{packageCompany}}</Company>
|
||||
<AssemblyTitle>{{packageTitle}}</AssemblyTitle>
|
||||
<Description>{{packageDescription}}</Description>
|
||||
<Copyright>{{packageCopyright}}</Copyright>
|
||||
<RootNamespace>{{packageName}}</RootNamespace>
|
||||
<Version>{{packageVersion}}</Version>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\{{packageName}}.xml</DocumentationFile>{{#licenseId}}
|
||||
<PackageLicenseExpression>{{licenseId}}</PackageLicenseExpression>{{/licenseId}}
|
||||
<RepositoryUrl>https://{{{gitHost}}}/{{{gitUserId}}}/{{{gitRepoId}}}.git</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>{{#releaseNote}}
|
||||
<PackageReleaseNotes>{{releaseNote}}</PackageReleaseNotes>{{/releaseNote}}{{#packageTags}}
|
||||
<PackageTags>{{{packageTags}}}</PackageTags>{{/packageTags}}
|
||||
{{#nullableReferenceTypes}}
|
||||
<Nullable>annotations</Nullable>
|
||||
{{/nullableReferenceTypes}}
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
{{#useCompareNetObjects}}
|
||||
<PackageReference Include="CompareNETObjects" Version="4.61.0" />
|
||||
{{/useCompareNetObjects}}
|
||||
<PackageReference Include="JsonSubTypes" Version="1.8.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
{{#useRestSharp}}
|
||||
<PackageReference Include="RestSharp" Version="106.11.7" />
|
||||
{{/useRestSharp}}
|
||||
{{#supportsRetry}}
|
||||
<PackageReference Include="Polly" Version="7.2.1" />
|
||||
{{/supportsRetry}}
|
||||
{{#validatable}}
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
{{/validatable}}
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyName>{{testPackageName}}</AssemblyName>
|
||||
<RootNamespace>{{testPackageName}}</RootNamespace>
|
||||
<TargetFramework{{#multiTarget}}s{{/multiTarget}}>{{testTargetFramework}}</TargetFramework{{#multiTarget}}s{{/multiTarget}}>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.2" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\{{packageName}}\{{packageName}}.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
52
modules/openapi-generator/src/main/resources/csharp-netcore-functions/nuspec.mustache
vendored
Normal file
52
modules/openapi-generator/src/main/resources/csharp-netcore-functions/nuspec.mustache
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<!-- The identifier that must be unique within the hosting gallery -->
|
||||
<id>$id$</id>
|
||||
<title>{{packageTitle}}</title>
|
||||
|
||||
<!-- The package version number that is used when resolving dependencies -->
|
||||
<version>$version$</version>
|
||||
|
||||
<!-- Authors contain text that appears directly on the gallery -->
|
||||
<authors>$author$</authors>
|
||||
|
||||
<!-- Owners are typically nuget.org identities that allow gallery
|
||||
users to earily find other packages by the same owners. -->
|
||||
<owners>$author$</owners>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<developmentDependency>false</developmentDependency>
|
||||
|
||||
<!-- The description can be used in package manager UI. Note that the
|
||||
nuget.org gallery uses information you add in the portal. -->
|
||||
<description>{{packageDescription}}</description>
|
||||
{{#termsOfService}}
|
||||
<copyright>{{termsOfService}}</copyright>
|
||||
{{/termsOfService}}
|
||||
{{#licenseUrl}}
|
||||
<licenseUrl>{{licenseUrl}}</licenseUrl>
|
||||
{{/licenseUrl}}
|
||||
|
||||
<!-- Dependencies are automatically installed when the package is installed -->
|
||||
<dependencies>
|
||||
|
||||
<dependency id="Newtonsoft.Json" version="12.0.3" />
|
||||
<dependency id="RestSharp" version="106.11.7" />
|
||||
{{#useCompareNetObjects}}
|
||||
<dependency id="CompareNETObjects" version="4.61.0" />
|
||||
{{/useCompareNetObjects}}
|
||||
<dependency id="JsonSubTypes" version="1.8.0" />
|
||||
{{#validatable}}
|
||||
<dependency id="System.ComponentModel.Annotations" version="5.0.0" />
|
||||
{{/validatable}}
|
||||
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
||||
<!-- A readme.txt will be displayed when the package is installed -->
|
||||
<file src="..\..\README.md" target="" />
|
||||
<file src="..\..\docs\**\*.*" target="docs" />
|
||||
|
||||
</files>
|
||||
</package>
|
17
modules/openapi-generator/src/main/resources/csharp-netcore-functions/partial_header.mustache
vendored
Normal file
17
modules/openapi-generator/src/main/resources/csharp-netcore-functions/partial_header.mustache
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
{{#appName}}
|
||||
* {{{appName}}}
|
||||
*
|
||||
{{/appName}}
|
||||
{{#appDescription}}
|
||||
* {{{appDescription}}}
|
||||
*
|
||||
{{/appDescription}}
|
||||
{{#version}}
|
||||
* The version of the OpenAPI document: {{{version}}}
|
||||
{{/version}}
|
||||
{{#infoEmail}}
|
||||
* Contact: {{{infoEmail}}}
|
||||
{{/infoEmail}}
|
||||
* Generated by: https://github.com/openapitools/openapi-generator.git
|
||||
*/
|
1
modules/openapi-generator/src/main/resources/csharp-netcore-functions/pathParam.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/csharp-netcore-functions/pathParam.mustache
vendored
Normal file
@ -0,0 +1 @@
|
||||
{{#isPathParam}}{{#pattern}}[RegularExpression("{{{pattern}}}")]{{/pattern}}{{#minLength}}{{#maxLength}}[StringLength({{maxLength}}, MinimumLength={{minLength}})]{{/maxLength}}{{/minLength}}{{#minLength}}{{^maxLength}} [MinLength({{minLength}})]{{/maxLength}}{{/minLength}}{{^minLength}}{{#maxLength}} [MaxLength({{maxLength}})]{{/maxLength}}{{/minLength}}{{#minimum}}{{#maximum}}[Range({{minimum}}, {{maximum}})]{{/maximum}}{{/minimum}}{{&dataType}} {{paramName}}{{/isPathParam}}
|
12
modules/openapi-generator/src/main/resources/csharp-netcore-functions/project.mustache
vendored
Normal file
12
modules/openapi-generator/src/main/resources/csharp-netcore-functions/project.mustache
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"supports": {},
|
||||
"dependencies": {
|
||||
"FubarCoder.RestSharp.Portable.Core": "4.0.7",
|
||||
"FubarCoder.RestSharp.Portable.HttpClient": "4.0.7",
|
||||
"Newtonsoft.Json": "10.0.3",
|
||||
"JsonSubTypes": "1.2.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"netstandard1.3": {}
|
||||
}
|
||||
}
|
1
modules/openapi-generator/src/main/resources/csharp-netcore-functions/visibility.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/csharp-netcore-functions/visibility.mustache
vendored
Normal file
@ -0,0 +1 @@
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}}
|
@ -11,7 +11,7 @@ class {{classname}} extends EnumClass {
|
||||
{{#description}}
|
||||
/// {{{.}}}
|
||||
{{/description}}
|
||||
@BuiltValueEnumConst({{#isInteger}}wireNumber: {{{value}}}{{/isInteger}}{{^isInteger}}wireName: r{{{value}}}{{/isInteger}})
|
||||
@BuiltValueEnumConst({{#isInteger}}wireNumber: {{{value}}}{{/isInteger}}{{#isLong}}wireNumber: {{{value}}}{{/isLong}}{{^isInteger}}{{^isLong}}wireName: r{{{value}}}{{/isLong}}{{/isInteger}})
|
||||
static const {{classname}} {{name}} = _${{name}};
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
|
@ -5,7 +5,7 @@ class {{{enumName}}} extends EnumClass {
|
||||
{{#description}}
|
||||
/// {{{.}}}
|
||||
{{/description}}
|
||||
@BuiltValueEnumConst({{#isInteger}}wireNumber: {{{value}}}{{/isInteger}}{{^isInteger}}wireName: r{{{value}}}{{/isInteger}})
|
||||
@BuiltValueEnumConst({{#isInteger}}wireNumber: {{{value}}}{{/isInteger}}{{#isLong}}wireNumber: {{{value}}}{{/isLong}}{{^isInteger}}{{^isLong}}wireName: r{{{value}}}{{/isLong}}{{/isInteger}})
|
||||
static const {{{enumName}}} {{name}} = _${{#lambda.camelcase}}{{{enumName}}}{{/lambda.camelcase}}_{{name}};
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
|
@ -19,17 +19,17 @@ part 'serializers.g.dart';
|
||||
@SerializersFor([{{#models}}{{#model}}
|
||||
{{classname}},{{/model}}{{/models}}
|
||||
])
|
||||
Serializers serializers = (_$serializers.toBuilder(){{#apiInfo}}{{#apis}}{{#serializers}}
|
||||
Serializers serializers = (_$serializers.toBuilder(){{#builtValueSerializers}}
|
||||
..addBuilderFactory(
|
||||
{{#isArray}}
|
||||
const FullType(Built{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}, [FullType({{baseType}})]),
|
||||
() => {{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}Builder<{{baseType}}>(),
|
||||
const FullType(Built{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}, [FullType{{#isNullable}}.nullable{{/isNullable}}({{dataType}})]),
|
||||
() => {{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}Builder<{{dataType}}>(),
|
||||
{{/isArray}}
|
||||
{{#isMap}}
|
||||
const FullType(BuiltMap, [FullType(String), FullType({{baseType}})]),
|
||||
() => MapBuilder<String, {{baseType}}>(),
|
||||
const FullType(BuiltMap, [FullType(String), FullType{{#isNullable}}.nullable{{/isNullable}}({{dataType}})]),
|
||||
() => MapBuilder<String, {{dataType}}>(),
|
||||
{{/isMap}}
|
||||
){{/serializers}}{{/apis}}{{/apiInfo}}{{#useDateLibTimeMachine}}
|
||||
){{/builtValueSerializers}}{{#useDateLibTimeMachine}}
|
||||
..add(const OffsetDateSerializer())
|
||||
..add(const OffsetDateTimeSerializer()){{/useDateLibTimeMachine}}{{#useDateLibCore}}
|
||||
..add(const DateSerializer())
|
||||
|
@ -134,7 +134,7 @@
|
||||
{{#responses}}
|
||||
<h4 class="field-label">{{code}}</h4>
|
||||
{{message}}
|
||||
{{#simpleType}}<a href="#{{dataType}}">{{dataType}}</a>{{/simpleType}}
|
||||
{{^containerType}}<a href="#{{dataType}}">{{dataType}}</a>{{/containerType}}
|
||||
{{#examples}}
|
||||
<h3 class="field-label">Example data</h3>
|
||||
<div class="example-data-content-type">Content-Type: {{{contentType}}}</div>
|
||||
|
@ -93,4 +93,7 @@ tasks {
|
||||
}
|
||||
}
|
||||
}
|
||||
register("test") {
|
||||
dependsOn("allTests")
|
||||
}
|
||||
}
|
||||
|
@ -34,15 +34,20 @@ import {{packageName}}.auth.*
|
||||
KotlinxSerializer(json).ignoreOutgoingContent()
|
||||
}
|
||||
|
||||
private val defaultHttpClientConfig: (HttpClientConfig<*>) -> Unit by lazy {
|
||||
val jsonConfig: JsonFeature.Config.() -> Unit = { this.serializer = this@ApiClient.serializer }
|
||||
{ it.install(JsonFeature, jsonConfig) }
|
||||
private val clientConfig: (HttpClientConfig<*>) -> Unit by lazy {
|
||||
{
|
||||
// Hold a reference to the serializer to avoid freezing the entire ApiClient instance
|
||||
// when the JsonFeature is configured.
|
||||
val serializerReference = serializer
|
||||
it.install(JsonFeature) { serializer = serializerReference }
|
||||
httpClientConfig?.invoke(it)
|
||||
}
|
||||
}
|
||||
|
||||
private val client: HttpClient by lazy {
|
||||
val clientConfig: (HttpClientConfig<*>) -> Unit = httpClientConfig ?: defaultHttpClientConfig
|
||||
httpClientEngine?.let { HttpClient(it, clientConfig) } ?: HttpClient(clientConfig)
|
||||
}
|
||||
|
||||
{{#hasAuthMethods}}
|
||||
private val authentications: kotlin.collections.Map<String, Authentication> by lazy {
|
||||
mapOf({{#authMethods}}{{#isBasic}}{{#isBasicBasic}}
|
||||
|
@ -19,7 +19,7 @@ This server has been generated with [Laminas (Zend) PSR-7 implementation](https:
|
||||
## Requirements
|
||||
|
||||
* Web server with URL rewriting
|
||||
* PHP 7.3 or newer
|
||||
* PHP 7.4 or newer
|
||||
|
||||
This package contains `.htaccess` for Apache configuration.
|
||||
If you use another server(Nginx, HHVM, IIS, lighttpd) check out [Web Servers](https://www.slimframework.com/docs/v3/start/web-servers.html) doc.
|
||||
|
@ -8,7 +8,7 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.3 || ^8.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"slim/slim": "^4.5.0",
|
||||
"dyorg/slim-token-authentication": "dev-slim4",
|
||||
"ybelenko/openapi-data-mocker": "^1.0",
|
||||
|
@ -2,7 +2,7 @@
|
||||
{{#appName}}
|
||||
* {{{.}}}
|
||||
{{/appName}}
|
||||
* PHP version 7.3
|
||||
* PHP version 7.4
|
||||
*
|
||||
* @package {{invokerPackage}}
|
||||
* @author OpenAPI Generator team
|
||||
|
@ -14,6 +14,28 @@ extension JSONEncodable {
|
||||
func encodeToJSON() -> Any { self }
|
||||
}
|
||||
|
||||
/// An enum where the last case value can be used as a default catch-all.
|
||||
protocol CaseIterableDefaultsLast: Decodable & CaseIterable & RawRepresentable
|
||||
where RawValue: Decodable, AllCases: BidirectionalCollection {}
|
||||
|
||||
extension CaseIterableDefaultsLast {
|
||||
/// Initializes an enum such that if a known raw value is found, then it is decoded.
|
||||
/// Otherwise the last case is used.
|
||||
/// - Parameter decoder: A decoder.
|
||||
public init(from decoder: Decoder) throws {
|
||||
if let value = try Self(rawValue: decoder.singleValueContainer().decode(RawValue.self)) {
|
||||
self = value
|
||||
} else if let lastValue = Self.allCases.last {
|
||||
self = lastValue
|
||||
} else {
|
||||
throw DecodingError.valueNotFound(
|
||||
Self.Type.self,
|
||||
.init(codingPath: decoder.codingPath, debugDescription: "CaseIterableDefaultsLast")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum ErrorResponse: Error {
|
||||
case error(Int, Data?, URLResponse?, Error)
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ extension {{projectName}}API {
|
||||
@available(*, deprecated, message: "This operation is deprecated.")
|
||||
{{/isDeprecated}}
|
||||
@discardableResult
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue, completion: @escaping ((_ data: {{{returnType}}}{{^returnType}}Void{{/returnType}}?, _ error: Error?) -> Void)) -> URLSessionTask? {
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue, completion: @escaping ((_ data: {{{returnType}}}{{^returnType}}Void{{/returnType}}?, _ error: Error?) -> Void)) -> URLSessionTask? {
|
||||
return {{operationId}}WithRequestBuilder({{#allParams}}{{paramName}}: {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).execute(apiResponseQueue) { result in
|
||||
switch result {
|
||||
{{#returnType}}
|
||||
@ -91,7 +91,7 @@ extension {{projectName}}API {
|
||||
{{#isDeprecated}}
|
||||
@available(*, deprecated, message: "This operation is deprecated.")
|
||||
{{/isDeprecated}}
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}} {{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue) -> Promise<{{{returnType}}}{{^returnType}}Void{{/returnType}}> {
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}} {{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue) -> Promise<{{{returnType}}}{{^returnType}}Void{{/returnType}}> {
|
||||
let deferred = Promise<{{{returnType}}}{{^returnType}}Void{{/returnType}}>.pending()
|
||||
{{operationId}}WithRequestBuilder({{#allParams}}{{paramName}}: {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).execute(apiResponseQueue) { result in
|
||||
switch result {
|
||||
@ -122,7 +122,7 @@ extension {{projectName}}API {
|
||||
{{#isDeprecated}}
|
||||
@available(*, deprecated, message: "This operation is deprecated.")
|
||||
{{/isDeprecated}}
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue) -> Observable<{{{returnType}}}{{^returnType}}Void{{/returnType}}> {
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue) -> Observable<{{{returnType}}}{{^returnType}}Void{{/returnType}}> {
|
||||
return Observable.create { observer -> Disposable in
|
||||
let task = {{operationId}}WithRequestBuilder({{#allParams}}{{paramName}}: {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).execute(apiResponseQueue) { result in
|
||||
switch result {
|
||||
@ -160,7 +160,7 @@ extension {{projectName}}API {
|
||||
@available(*, deprecated, message: "This operation is deprecated.")
|
||||
{{/isDeprecated}}
|
||||
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue) -> AnyPublisher<{{{returnType}}}{{^returnType}}Void{{/returnType}}, Error> {
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue) -> AnyPublisher<{{{returnType}}}{{^returnType}}Void{{/returnType}}, Error> {
|
||||
var task: URLSessionTask?
|
||||
return Future<{{{returnType}}}{{^returnType}}Void{{/returnType}}, Error> { promise in
|
||||
task = {{operationId}}WithRequestBuilder({{#allParams}}{{paramName}}: {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).execute(apiResponseQueue) { result in
|
||||
@ -198,7 +198,7 @@ extension {{projectName}}API {
|
||||
@available(*, deprecated, message: "This operation is deprecated.")
|
||||
{{/isDeprecated}}
|
||||
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue) async throws{{#returnType}} -> {{{returnType}}}{{/returnType}} {
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue) async throws{{#returnType}} -> {{{returnType}}}{{/returnType}} {
|
||||
var task: URLSessionTask?
|
||||
return try await withTaskCancellationHandler {
|
||||
try Task.checkCancellation()
|
||||
@ -241,7 +241,7 @@ extension {{projectName}}API {
|
||||
@available(*, deprecated, message: "This operation is deprecated.")
|
||||
{{/isDeprecated}}
|
||||
@discardableResult
|
||||
open class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue, completion: @escaping ((_ result: Swift.Result<{{{returnType}}}{{^returnType}}Void{{/returnType}}, ErrorResponse>) -> Void)) -> URLSessionTask? {
|
||||
open class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}apiResponseQueue: DispatchQueue = {{projectName}}API.apiResponseQueue, completion: @escaping ((_ result: Swift.Result<{{{returnType}}}{{^returnType}}Void{{/returnType}}, ErrorResponse>) -> Void)) -> URLSessionTask? {
|
||||
return {{operationId}}WithRequestBuilder({{#allParams}}{{paramName}}: {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).execute(apiResponseQueue) { result in
|
||||
switch result {
|
||||
{{#returnType}}
|
||||
@ -411,7 +411,7 @@ extension {{projectName}}API {
|
||||
{{#isDeprecated}}
|
||||
@available(*, deprecated, message: "This operation is deprecated.")
|
||||
{{/isDeprecated}}
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}WithRequestBuilder({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> RequestBuilder<{{{returnType}}}{{^returnType}}Void{{/returnType}}> {
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}WithRequestBuilder({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> RequestBuilder<{{{returnType}}}{{^returnType}}Void{{/returnType}}> {
|
||||
{{^pathParams}}let{{/pathParams}}{{#pathParams}}{{#-first}}var{{/-first}}{{/pathParams}} localVariablePath = "{{{path}}}"{{#pathParams}}
|
||||
let {{paramName}}PreEscape = "\({{#isEnum}}{{paramName}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}.rawValue{{/isContainer}}{{/isEnum}}{{^isEnum}}APIHelper.mapValueToPathItem({{paramName}}){{/isEnum}})"
|
||||
let {{paramName}}PostEscape = {{paramName}}PreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? ""
|
||||
|
@ -15,18 +15,18 @@ Method | HTTP request | Description
|
||||
{{^usePromiseKit}}
|
||||
{{^useRxSwift}}
|
||||
{{^useVapor}}
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}completion: @escaping (_ data: {{{returnType}}}{{^returnType}}Void{{/returnType}}?, _ error: Error?) -> Void)
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}completion: @escaping (_ data: {{{returnType}}}{{^returnType}}Void{{/returnType}}?, _ error: Error?) -> Void)
|
||||
{{/useVapor}}
|
||||
{{/useRxSwift}}
|
||||
{{/usePromiseKit}}
|
||||
{{#usePromiseKit}}
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}} {{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Promise<{{{returnType}}}{{^returnType}}Void{{/returnType}}>
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}} {{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Promise<{{{returnType}}}{{^returnType}}Void{{/returnType}}>
|
||||
{{/usePromiseKit}}
|
||||
{{#useRxSwift}}
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Observable<{{{returnType}}}{{^returnType}}Void{{/returnType}}>
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Observable<{{{returnType}}}{{^returnType}}Void{{/returnType}}>
|
||||
{{/useRxSwift}}
|
||||
{{#useVapor}}
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}headers: HTTPHeaders = {{projectName}}API.customHeaders, beforeSend: (inout ClientRequest) throws -> () = { _ in }) -> EventLoopFuture<{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}>
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}[{{enumName}}_{{operationId}}]{{/isContainer}}{{^isContainer}}{{enumName}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}{{#hasParams}}, {{/hasParams}}headers: HTTPHeaders = {{projectName}}API.customHeaders, beforeSend: (inout ClientRequest) throws -> () = { _ in }) -> EventLoopFuture<{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}>
|
||||
{{/useVapor}}
|
||||
```
|
||||
|
||||
|
@ -1,7 +1,32 @@
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum {{classname}}: {{dataType}}, {{#useVapor}}Content, Hashable{{/useVapor}}{{^useVapor}}Codable{{/useVapor}}, CaseIterable {
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum {{classname}}: {{dataType}}, {{#useVapor}}Content, Hashable{{/useVapor}}{{^useVapor}}Codable{{/useVapor}}, CaseIterable{{^generateFrozenEnums}}{{#isInteger}}, CaseIterableDefaultsLast{{/isInteger}}{{#isFloat}}, CaseIterableDefaultsLast{{/isFloat}}{{#isDouble}}, CaseIterableDefaultsLast{{/isDouble}}{{#isString}}, CaseIterableDefaultsLast{{/isString}}{{/generateFrozenEnums}} {
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
case {{{name}}} = {{{value}}}
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
{{^generateFrozenEnums}}
|
||||
// This case is a catch-all generated by OpenAPI such that the enum is "non-frozen".
|
||||
// If new enum cases are added that are unknown to the spec/client, they are safely
|
||||
// decoded to this case. The raw value of this case is a dummy value that attempts
|
||||
// to avoids collisions with previously specified cases.
|
||||
{{#isString}}
|
||||
case unknownDefaultOpenAPI = "unknown_default_open_api"
|
||||
{{/isString}}
|
||||
{{#isNumeric}}
|
||||
//
|
||||
// 192, used to calculate the raw value, was the Swift Evolution proposal for
|
||||
// frozen/non-frozen enums.
|
||||
// [SE-0192](https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md)
|
||||
//
|
||||
{{/isNumeric}}
|
||||
{{#isInteger}}
|
||||
case unknownDefaultOpenAPI = -11184809 // Int.min / 192
|
||||
{{/isInteger}}
|
||||
{{#isDouble}}
|
||||
case unknownDefaultOpenAPI = -11184809 // Int.min / 192
|
||||
{{/isDouble}}
|
||||
{{#isFloat}}
|
||||
case unknownDefaultOpenAPI = -11184809 // Int.min / 192
|
||||
{{/isFloat}}
|
||||
{{/generateFrozenEnums}}
|
||||
}
|
@ -1,7 +1,35 @@
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum {{enumName}}: {{^isContainer}}{{dataType}}{{/isContainer}}{{#isContainer}}String{{/isContainer}}, {{#useVapor}}Content, Hashable{{/useVapor}}{{^useVapor}}Codable{{/useVapor}}, CaseIterable {
|
||||
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum {{enumName}}: {{^isContainer}}{{dataType}}{{/isContainer}}{{#isContainer}}String{{/isContainer}}, {{#useVapor}}Content, Hashable{{/useVapor}}{{^useVapor}}Codable{{/useVapor}}, CaseIterable{{^generateFrozenEnums}}{{#isInteger}}, CaseIterableDefaultsLast{{/isInteger}}{{#isFloat}}, CaseIterableDefaultsLast{{/isFloat}}{{#isDouble}}, CaseIterableDefaultsLast{{/isDouble}}{{#isString}}, CaseIterableDefaultsLast{{/isString}}{{#isContainer}}, CaseIterableDefaultsLast{{/isContainer}}{{/generateFrozenEnums}} {
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
case {{{name}}} = {{{value}}}
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
{{^generateFrozenEnums}}
|
||||
// This case is a catch-all generated by OpenAPI such that the enum is "non-frozen".
|
||||
// If new enum cases are added that are unknown to the spec/client, they are safely
|
||||
// decoded to this case. The raw value of this case is a dummy value that attempts
|
||||
// to avoids collisions with previously specified cases.
|
||||
{{#isString}}
|
||||
case unknownDefaultOpenAPI = "unknown_default_open_api"
|
||||
{{/isString}}
|
||||
{{#isContainer}}
|
||||
case unknownDefaultOpenAPI = "unknown_default_open_api"
|
||||
{{/isContainer}}
|
||||
{{#isNumeric}}
|
||||
//
|
||||
// 192, used to calculate the raw value, was the Swift Evolution proposal for
|
||||
// frozen/non-frozen enums.
|
||||
// [SE-0192](https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md)
|
||||
//
|
||||
{{/isNumeric}}
|
||||
{{#isInteger}}
|
||||
case unknownDefaultOpenAPI = -11184809 // Int.min / 192
|
||||
{{/isInteger}}
|
||||
{{#isDouble}}
|
||||
case unknownDefaultOpenAPI = -11184809 // Int.min / 192
|
||||
{{/isDouble}}
|
||||
{{#isFloat}}
|
||||
case unknownDefaultOpenAPI = -11184809 // Int.min / 192
|
||||
{{/isFloat}}
|
||||
{{/generateFrozenEnums}}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
public enum {{classname}}: {{#useVapor}}Content{{/useVapor}}{{^useVapor}}Codable{{/useVapor}} {
|
||||
public enum {{classname}}: {{#useVapor}}Content{{/useVapor}}{{^useVapor}}Codable{{#vendorExtensions.x-swift-hashable}}, Hashable{{/vendorExtensions.x-swift-hashable}}{{/useVapor}} {
|
||||
{{#oneOf}}
|
||||
case type{{.}}({{.}})
|
||||
{{/oneOf}}
|
||||
|
@ -3877,6 +3877,59 @@ public class DefaultCodegenTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponses() {
|
||||
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/response-tests.yaml");
|
||||
final DefaultCodegen codegen = new DefaultCodegen();
|
||||
codegen.setOpenAPI(openAPI);
|
||||
codegen.setDisallowAdditionalPropertiesIfNotPresent(false);
|
||||
|
||||
String path;
|
||||
Operation operation;
|
||||
CodegenOperation co;
|
||||
CodegenParameter cpa;
|
||||
CodegenResponse cr;
|
||||
|
||||
path = "/pet/{petId}";
|
||||
operation = openAPI.getPaths().get(path).getGet();
|
||||
co = codegen.fromOperation(path, "GET", operation, null);
|
||||
//assertTrue(co.hasErrorResponseObject);
|
||||
cr = co.responses.get(0);
|
||||
assertTrue(cr.is2xx);
|
||||
assertFalse(cr.simpleType);
|
||||
assertFalse(cr.primitiveType);
|
||||
cr = co.responses.get(3);
|
||||
assertTrue(cr.is5xx);
|
||||
assertFalse(cr.simpleType);
|
||||
assertFalse(cr.primitiveType);
|
||||
|
||||
path = "/pet";
|
||||
operation = openAPI.getPaths().get(path).getPut();
|
||||
co = codegen.fromOperation(path, "PUT", operation, null);
|
||||
assertTrue(co.hasErrorResponseObject);
|
||||
|
||||
// 200 response
|
||||
cr = co.responses.get(0);
|
||||
assertTrue(cr.is2xx);
|
||||
assertFalse(cr.simpleType);
|
||||
assertFalse(cr.primitiveType);
|
||||
|
||||
// 400 response
|
||||
cr = co.responses.get(1);
|
||||
assertTrue(cr.is4xx);
|
||||
assertEquals(cr.code, "400");
|
||||
assertFalse(cr.simpleType);
|
||||
assertFalse(cr.primitiveType);
|
||||
|
||||
path = "/pet/findByTags";
|
||||
operation = openAPI.getPaths().get(path).getGet();
|
||||
co = codegen.fromOperation(path, "GET", operation, null);
|
||||
assertFalse(co.hasErrorResponseObject);
|
||||
cr = co.responses.get(0);
|
||||
assertTrue(cr.is2xx);
|
||||
assertFalse(cr.simpleType);
|
||||
assertFalse(cr.primitiveType);
|
||||
}
|
||||
|
||||
public void testParameterContent() {
|
||||
DefaultCodegen codegen = new DefaultCodegen();
|
||||
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/content-data.yaml");
|
||||
@ -3922,11 +3975,13 @@ public class DefaultCodegenTest {
|
||||
CodegenMediaType mt = content.get("application/json");
|
||||
assertNull(mt.getEncoding());
|
||||
CodegenProperty cp = mt.getSchema();
|
||||
assertEquals(cp.baseName, "ApplicationJsonSchema");
|
||||
assertNotNull(cp);
|
||||
|
||||
mt = content.get("text/plain");
|
||||
assertNull(mt.getEncoding());
|
||||
cp = mt.getSchema();
|
||||
assertEquals(cp.baseName, "TextPlainSchema");
|
||||
assertNotNull(cp);
|
||||
// Note: the inline model resolver has a bug for this use case; it extracts an inline request body into a component
|
||||
// but the schema it references is not string type
|
||||
@ -3940,11 +3995,13 @@ public class DefaultCodegenTest {
|
||||
mt = content.get("application/json");
|
||||
assertNull(mt.getEncoding());
|
||||
cp = mt.getSchema();
|
||||
assertEquals(cp.baseName, "ApplicationJsonSchema");
|
||||
assertEquals(cp.complexType, "coordinates");
|
||||
|
||||
mt = content.get("text/plain");
|
||||
assertNull(mt.getEncoding());
|
||||
cp = mt.getSchema();
|
||||
assertEquals(cp.baseName, "TextPlainSchema");
|
||||
assertTrue(cp.isString);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2020 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openapitools.codegen.CsharpNetcoreFunctionsServerCodegen;
|
||||
|
||||
import org.openapitools.codegen.languages.CsharpNetcoreFunctionsServerCodegen;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class CsharpNetcoreFunctionsServerCodegenTest {
|
||||
|
||||
@Test
|
||||
public void testToEnumVarName() throws Exception {
|
||||
final CsharpNetcoreFunctionsServerCodegen codegen = new CsharpNetcoreFunctionsServerCodegen();
|
||||
codegen.processOpts();
|
||||
|
||||
Assert.assertEquals(codegen.toEnumVarName("FooBar", "string"), "FooBar");
|
||||
Assert.assertEquals(codegen.toEnumVarName("fooBar", "string"), "FooBar");
|
||||
Assert.assertEquals(codegen.toEnumVarName("foo-bar", "string"), "FooBar");
|
||||
Assert.assertEquals(codegen.toEnumVarName("foo_bar", "string"), "FooBar");
|
||||
Assert.assertEquals(codegen.toEnumVarName("foo bar", "string"), "FooBar");
|
||||
|
||||
// The below cases do not work currently, camelize doesn't support uppercase
|
||||
// Assert.assertEquals(codegen.toEnumVarName("FOO-BAR", "string"), "FooBar");
|
||||
// Assert.assertEquals(codegen.toEnumVarName("FOO_BAR", "string"), "FooBar");
|
||||
}
|
||||
}
|
@ -48,6 +48,7 @@ public class Swift5OptionsProvider implements OptionsProvider {
|
||||
public static final String REMOVE_MIGRATION_PROJECT_NAME_CLASS_VALUE = "false";
|
||||
public static final String SWIFT_USE_API_NAMESPACE_VALUE = "swiftUseApiNamespace";
|
||||
public static final String USE_BACKTICKS_ESCAPES_VALUE = "false";
|
||||
public static final String GENERATE_FROZEN_ENUMS_VALUE = "true";
|
||||
public static final String GENERATE_MODEL_ADDITIONAL_PROPERTIES_VALUE = "true";
|
||||
public static final String HASHABLE_MODELS_VALUE = "true";
|
||||
public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false";
|
||||
@ -95,6 +96,7 @@ public class Swift5OptionsProvider implements OptionsProvider {
|
||||
.put(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT, "true")
|
||||
.put(Swift5ClientCodegen.USE_SPM_FILE_STRUCTURE, USE_SPM_FILE_STRUCTURE_VALUE)
|
||||
.put(Swift5ClientCodegen.SWIFT_PACKAGE_PATH, SWIFT_PACKAGE_PATH_VALUE)
|
||||
.put(Swift5ClientCodegen.GENERATE_FROZEN_ENUMS, GENERATE_FROZEN_ENUMS_VALUE)
|
||||
.put(Swift5ClientCodegen.GENERATE_MODEL_ADDITIONAL_PROPERTIES, GENERATE_MODEL_ADDITIONAL_PROPERTIES_VALUE)
|
||||
.put(Swift5ClientCodegen.HASHABLE_MODELS, HASHABLE_MODELS_VALUE)
|
||||
.put(Swift5ClientCodegen.MAP_FILE_BINARY_TO_DATA, "false")
|
||||
|
@ -49,6 +49,7 @@ public class Swift5OptionsTest extends AbstractOptionsTest {
|
||||
verify(clientCodegen).setPrependFormOrBodyParameters(Boolean.valueOf(Swift5OptionsProvider.PREPEND_FORM_OR_BODY_PARAMETERS_VALUE));
|
||||
verify(clientCodegen).setReadonlyProperties(Boolean.parseBoolean(Swift5OptionsProvider.READONLY_PROPERTIES_VALUE));
|
||||
verify(clientCodegen).setRemoveMigrationProjectNameClass(Boolean.parseBoolean(Swift5OptionsProvider.REMOVE_MIGRATION_PROJECT_NAME_CLASS_VALUE));
|
||||
verify(clientCodegen).setGenerateFrozenEnums(Boolean.parseBoolean(Swift5OptionsProvider.GENERATE_FROZEN_ENUMS_VALUE));
|
||||
verify(clientCodegen).setGenerateModelAdditionalProperties(Boolean.parseBoolean(Swift5OptionsProvider.GENERATE_MODEL_ADDITIONAL_PROPERTIES_VALUE));
|
||||
verify(clientCodegen).setHashableModels(Boolean.parseBoolean(Swift5OptionsProvider.HASHABLE_MODELS_VALUE));
|
||||
}
|
||||
|
@ -8,14 +8,18 @@ import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.media.StringSchema;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponses;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.CodegenOperation;
|
||||
import org.openapitools.codegen.CodegenProperty;
|
||||
import org.openapitools.codegen.TestUtils;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.config.CodegenConfigurator;
|
||||
import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class TypeScriptAngularClientCodegenTest {
|
||||
@Test
|
||||
@ -267,4 +271,44 @@ public class TypeScriptAngularClientCodegenTest {
|
||||
codegen.importMapping().put(importedModel, importName);
|
||||
Assert.assertEquals(codegen.toModelImport(importedModel), importName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTaggedUnionImports() throws Exception {
|
||||
final String specPath = "src/test/resources/3_0/allOf_composition_discriminator_recursive.yaml";
|
||||
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put(TypeScriptAngularClientCodegen.TAGGED_UNIONS, "true");
|
||||
|
||||
File output = Files.createTempDirectory("test").toFile();
|
||||
output.deleteOnExit();
|
||||
|
||||
final CodegenConfigurator configurator = new CodegenConfigurator()
|
||||
.setGeneratorName("typescript-angular")
|
||||
.setInputSpec(specPath)
|
||||
.setAdditionalProperties(properties)
|
||||
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
|
||||
|
||||
final ClientOptInput clientOptInput = configurator.toClientOptInput();
|
||||
|
||||
Generator generator = new DefaultGenerator();
|
||||
generator.opts(clientOptInput).generate();
|
||||
|
||||
TestUtils.assertFileContains(
|
||||
Paths.get(output + "/model/expressionToken.ts"),
|
||||
"import { Token } from './token'", // imports the parent schema
|
||||
"import { TokenMetadata } from './tokenMetadata'", // imports a schema referenced in an inherited property
|
||||
"export interface ExpressionToken {" // no inheritance
|
||||
);
|
||||
|
||||
TestUtils.assertFileNotContains(
|
||||
Paths.get(output + "/model/stringToken.ts"),
|
||||
"import { Token } from './token'"
|
||||
);
|
||||
|
||||
TestUtils.assertFileContains(
|
||||
Paths.get(output + "/model/token.ts"),
|
||||
"import { ExpressionToken } from './expressionToken'",
|
||||
"export type Token = ExpressionToken | StringToken"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
openapi: 3.0.2
|
||||
info:
|
||||
title: OAI Specification example for Polymorphism
|
||||
version: 1.0.0
|
||||
paths:
|
||||
/status:
|
||||
get:
|
||||
responses:
|
||||
'201':
|
||||
description: desc
|
||||
|
||||
components:
|
||||
schemas:
|
||||
TokenMetadata:
|
||||
type: object
|
||||
properties:
|
||||
tag1:
|
||||
type: string
|
||||
|
||||
Token:
|
||||
type: object
|
||||
required:
|
||||
- type
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
metadata:
|
||||
$ref: '#/components/schemas/TokenMetadata'
|
||||
discriminator:
|
||||
propertyName: type
|
||||
mapping:
|
||||
string: '#/components/schemas/StringToken'
|
||||
expression: '#/components/schemas/ExpressionToken'
|
||||
|
||||
StringToken:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Token'
|
||||
- type: object
|
||||
properties:
|
||||
value:
|
||||
type: string
|
||||
|
||||
ExpressionToken:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Token'
|
||||
- type: object
|
||||
properties:
|
||||
tokens:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Token'
|
@ -0,0 +1,571 @@
|
||||
openapi: 3.0.0
|
||||
servers:
|
||||
- url: 'http://petstore.swagger.io/v2'
|
||||
info:
|
||||
description: >-
|
||||
This is a sample server Petstore server. For this sample, you can use the api key
|
||||
`special-key` to test the authorization filters.
|
||||
version: 1.0.0
|
||||
title: OpenAPI Petstore
|
||||
license:
|
||||
name: Apache-2.0
|
||||
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
|
||||
tags:
|
||||
- name: pet
|
||||
description: Everything about your Pets
|
||||
- name: store
|
||||
description: Access to Petstore orders
|
||||
- name: user
|
||||
description: Operations about user
|
||||
paths:
|
||||
/pet:
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Add a new pet to the store
|
||||
description: ''
|
||||
operationId: addPet
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'405':
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/Pet'
|
||||
put:
|
||||
tags:
|
||||
- pet
|
||||
summary: Update an existing pet
|
||||
description: ''
|
||||
operationId: updatePet
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
'404':
|
||||
description: Pet not found
|
||||
'405':
|
||||
description: Validation exception
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/Pet'
|
||||
/pet/findByStatus:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by status
|
||||
description: Multiple status values can be provided with comma separated strings
|
||||
operationId: findPetsByStatus
|
||||
parameters:
|
||||
- name: status
|
||||
in: query
|
||||
description: Status values that need to be considered for filter
|
||||
required: true
|
||||
style: form
|
||||
explode: false
|
||||
deprecated: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- available
|
||||
- pending
|
||||
- sold
|
||||
default: available
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid status value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'read:pets'
|
||||
/pet/findByTags:
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Finds Pets by tags
|
||||
description: >-
|
||||
Multiple tags can be provided with comma separated strings. Use tag1,
|
||||
tag2, tag3 for testing.
|
||||
operationId: findPetsByTags
|
||||
parameters:
|
||||
- name: tags
|
||||
in: query
|
||||
description: Tags to filter by
|
||||
required: true
|
||||
style: form
|
||||
explode: false
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid tag value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'read:pets'
|
||||
deprecated: true
|
||||
'/pet/{petId}':
|
||||
get:
|
||||
tags:
|
||||
- pet
|
||||
summary: Find pet by ID
|
||||
description: Returns a single pet
|
||||
operationId: getPetById
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet to return
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Pet not found
|
||||
'500':
|
||||
description: Server error
|
||||
content:
|
||||
application/application:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
security:
|
||||
- api_key: []
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: Updates a pet in the store with form data
|
||||
description: ''
|
||||
operationId: updatePetWithForm
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet that needs to be updated
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'405':
|
||||
description: Invalid input
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
description: Updated name of the pet
|
||||
type: string
|
||||
status:
|
||||
description: Updated status of the pet
|
||||
type: string
|
||||
delete:
|
||||
tags:
|
||||
- pet
|
||||
summary: Deletes a pet
|
||||
description: ''
|
||||
operationId: deletePet
|
||||
parameters:
|
||||
- name: api_key
|
||||
in: header
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: petId
|
||||
in: path
|
||||
description: Pet id to delete
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid pet value
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
'/pet/{petId}/uploadImage':
|
||||
post:
|
||||
tags:
|
||||
- pet
|
||||
summary: uploads an image
|
||||
description: ''
|
||||
operationId: uploadFile
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
description: ID of pet to update
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
security:
|
||||
- petstore_auth:
|
||||
- 'write:pets'
|
||||
- 'read:pets'
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
additionalMetadata:
|
||||
description: Additional data to pass to server
|
||||
type: string
|
||||
file:
|
||||
description: file to upload
|
||||
type: string
|
||||
format: binary
|
||||
'/store/order/{orderId}':
|
||||
get:
|
||||
tags:
|
||||
- store
|
||||
summary: Find purchase order by ID
|
||||
description: >-
|
||||
For valid response try integer IDs with value <= 5 or > 10. Other values
|
||||
will generated exceptions
|
||||
operationId: getOrderById
|
||||
parameters:
|
||||
- name: orderId
|
||||
in: path
|
||||
description: ID of pet that needs to be fetched
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 1
|
||||
maximum: 5
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Order'
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Order not found
|
||||
'500':
|
||||
description: Server error
|
||||
delete:
|
||||
tags:
|
||||
- store
|
||||
summary: Delete purchase order by ID
|
||||
description: >-
|
||||
For valid response try integer IDs with value < 1000. Anything above
|
||||
1000 or nonintegers will generate API errors
|
||||
operationId: deleteOrder
|
||||
parameters:
|
||||
- name: orderId
|
||||
in: path
|
||||
description: ID of the order that needs to be deleted
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'400':
|
||||
description: Invalid ID supplied
|
||||
'404':
|
||||
description: Order not found
|
||||
/user/login:
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
summary: Logs user into the system
|
||||
description: ''
|
||||
operationId: loginUser
|
||||
parameters:
|
||||
- name: username
|
||||
in: query
|
||||
description: The user name for login
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
|
||||
- name: password
|
||||
in: query
|
||||
description: The password for login in clear text
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
headers:
|
||||
Set-Cookie:
|
||||
description: >-
|
||||
Cookie authentication key for use with the `api_key`
|
||||
apiKey authentication.
|
||||
schema:
|
||||
type: string
|
||||
example: AUTH_KEY=abcde12345; Path=/; HttpOnly
|
||||
X-Rate-Limit:
|
||||
description: calls per hour allowed by the user
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
X-Expires-After:
|
||||
description: date in UTC when token expires
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
content:
|
||||
application/xml:
|
||||
schema:
|
||||
type: string
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
'400':
|
||||
description: Invalid username/password supplied
|
||||
externalDocs:
|
||||
description: Find out more about Swagger
|
||||
url: 'http://swagger.io'
|
||||
components:
|
||||
requestBodies:
|
||||
UserArray:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/User'
|
||||
description: List of user object
|
||||
required: true
|
||||
Pet:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
description: Pet object that needs to be added to the store
|
||||
required: true
|
||||
securitySchemes:
|
||||
petstore_auth:
|
||||
type: oauth2
|
||||
flows:
|
||||
implicit:
|
||||
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
|
||||
scopes:
|
||||
'write:pets': modify pets in your account
|
||||
'read:pets': read your pets
|
||||
api_key:
|
||||
type: apiKey
|
||||
name: api_key
|
||||
in: header
|
||||
schemas:
|
||||
Order:
|
||||
title: Pet Order
|
||||
description: An order for a pets from the pet store
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
petId:
|
||||
type: integer
|
||||
format: int64
|
||||
quantity:
|
||||
type: integer
|
||||
format: int32
|
||||
shipDate:
|
||||
type: string
|
||||
format: date-time
|
||||
status:
|
||||
type: string
|
||||
description: Order Status
|
||||
enum:
|
||||
- placed
|
||||
- approved
|
||||
- delivered
|
||||
complete:
|
||||
type: boolean
|
||||
default: false
|
||||
xml:
|
||||
name: Order
|
||||
Category:
|
||||
title: Pet category
|
||||
description: A category for a pet
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
|
||||
xml:
|
||||
name: Category
|
||||
User:
|
||||
title: a User
|
||||
description: A User who is purchasing from the pet store
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
username:
|
||||
type: string
|
||||
firstName:
|
||||
type: string
|
||||
lastName:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
phone:
|
||||
type: string
|
||||
userStatus:
|
||||
type: integer
|
||||
format: int32
|
||||
description: User Status
|
||||
xml:
|
||||
name: User
|
||||
Tag:
|
||||
title: Pet Tag
|
||||
description: A tag for a pet
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
xml:
|
||||
name: Tag
|
||||
Pet:
|
||||
title: a Pet
|
||||
description: A pet for sale in the pet store
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- photoUrls
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
category:
|
||||
$ref: '#/components/schemas/Category'
|
||||
name:
|
||||
type: string
|
||||
example: doggie
|
||||
photoUrls:
|
||||
type: array
|
||||
xml:
|
||||
name: photoUrl
|
||||
wrapped: true
|
||||
items:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
xml:
|
||||
name: tag
|
||||
wrapped: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Tag'
|
||||
status:
|
||||
type: string
|
||||
description: pet status in the store
|
||||
deprecated: true
|
||||
enum:
|
||||
- available
|
||||
- pending
|
||||
- sold
|
||||
xml:
|
||||
name: Pet
|
||||
ApiResponse:
|
||||
title: An uploaded response
|
||||
description: Describes the result of uploading an image resource
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
type:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
78
openapi-generator.code-workspace
Normal file
78
openapi-generator.code-workspace
Normal file
@ -0,0 +1,78 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "openapi-generator",
|
||||
"path": "."
|
||||
},
|
||||
{
|
||||
"name": "openapi-generator-cli",
|
||||
"path": "modules/openapi-generator-cli"
|
||||
},
|
||||
{
|
||||
"name": "openapi-generator-core",
|
||||
"path": "modules/openapi-generator-core"
|
||||
},
|
||||
{
|
||||
"name": "openapi-generator-gradle-plugin",
|
||||
"path": "modules/openapi-generator-gradle-plugin"
|
||||
},
|
||||
{
|
||||
"name": "openapi-generator-maven-plugin",
|
||||
"path": "modules/openapi-generator-maven-plugin"
|
||||
},
|
||||
{
|
||||
"name": "openapi-generator-online",
|
||||
"path": "modules/openapi-generator-online"
|
||||
},
|
||||
],
|
||||
"settings": {
|
||||
"editor.formatOnType": true,
|
||||
"editor.linkedEditing": true,
|
||||
"editor.tabCompletion": "on",
|
||||
"editor.tabSize": 4,
|
||||
"editor.renderWhitespace": "boundary",
|
||||
"editor.suggest.shareSuggestSelections": true,
|
||||
"editor.suggestSelection": "first",
|
||||
"editor.semanticHighlighting.enabled": true,
|
||||
"explorer.confirmDelete": true,
|
||||
|
||||
"files.autoSave": "onFocusChange",
|
||||
"files.exclude": {
|
||||
"**/.classpath": true,
|
||||
"**/.factorypath": true,
|
||||
"**/.project": true,
|
||||
"**/.settings": true
|
||||
},
|
||||
"files.trimFinalNewlines": false,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
|
||||
"task.saveBeforeRun": "always",
|
||||
|
||||
"java.autobuild.enabled": false,
|
||||
"java.completion.enabled": true,
|
||||
"java.completion.guessMethodArguments": true,
|
||||
"java.completion.maxResults": 5,
|
||||
"java.format.onType.enabled": true,
|
||||
|
||||
"java.referencesCodeLens.enabled": true,
|
||||
"java.saveActions.organizeImports": true,
|
||||
"java.showBuildStatusOnStart.enabled": true,
|
||||
|
||||
"java.dependency.autoRefresh": true,
|
||||
"java.dependency.refreshDelay": 3000,
|
||||
"java.format.enabled": true,
|
||||
|
||||
"maven.pomfile.autoUpdateEffectivePOM": true,
|
||||
},
|
||||
"extensions": {
|
||||
"recommendations": [
|
||||
"vscjava.vscode-java-pack",
|
||||
"attilabuti.mustache-syntax-vscode",
|
||||
"formulahendry.code-runner",
|
||||
"visualstudioexptteam.vscodeintellicode",
|
||||
"42crunch.vscode-openapi",
|
||||
"mermade.openapi-lint"
|
||||
|
||||
]
|
||||
}
|
||||
}
|
1
pom.xml
1
pom.xml
@ -1434,6 +1434,7 @@
|
||||
<module>samples/client/petstore/swift5/combineLibrary</module>
|
||||
<module>samples/client/petstore/swift5/default</module>
|
||||
<module>samples/client/petstore/swift5/deprecated</module>
|
||||
<module>samples/client/petstore/swift5/frozenEnums</module>
|
||||
<module>samples/client/petstore/swift5/nonPublicApi</module>
|
||||
<module>samples/client/petstore/swift5/objcCompatible</module>
|
||||
<module>samples/client/petstore/swift5/promisekitLibrary</module>
|
||||
|
@ -221,7 +221,6 @@ public class JSON {
|
||||
.registerTypeAdapter(LocalDate.class, localDateTypeAdapter)
|
||||
.registerTypeAdapter(byte[].class, byteArrayAdapter)
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.AdditionalPropertiesClass.CustomTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.Animal.CustomTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.Apple.CustomTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.AppleReq.CustomTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.ArrayOfArrayOfNumberOnly.CustomTypeAdapterFactory())
|
||||
@ -251,7 +250,6 @@ public class JSON {
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.Fruit.CustomTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.FruitReq.CustomTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.GmFruit.CustomTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.GrandparentAnimal.CustomTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.HasOnlyReadOnly.CustomTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.HealthCheckResult.CustomTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(new org.openapitools.client.model.InlineResponseDefault.CustomTypeAdapterFactory())
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user