Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • O openapi-generator
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,476
    • Issues 3,476
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 402
    • Merge requests 402
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • OpenAPI Tools
  • openapi-generator
  • Merge requests
  • !5059

[aspnetcore] Fix duplicate enums

  • Review changes

  • Download
  • Email patches
  • Plain diff
Merged Jim Schubert requested to merge github/fork/jimschubert/fix-aspnetcore-duplicate-enums into master Jan 20, 2020
  • Overview 0
  • Commits 2
  • Pipelines 0
  • Changes 8

Fixes #5024 (closed). aspnetcore templates previously ignored the complexType property which indicates whether it's an inline enum or a reference to another type in the namespace.

Given openapi.yaml with enum as model:

openapi: '3.0.0'
info:
  version: 1.0.0
  title: API with Default Values
servers:
  - url: http://localhost:8080
paths:
  /test:
    post:
      operationId: testDefaults
      requestBody:
        required: true
        content:
          application/json:
            schema:
              '$ref': '#/components/schemas/Payload'
      responses:
        '200':
          description: Ok
components:
  schemas:
    Payload:
      type: object
      properties:
        stringProp:
          type: string
          default: foo
        doubleProp:
          type: number
          format: double
          default: 1.234
        enumProp:
          $ref: '#/components/schemas/EnumProp'
    EnumProp:
          type: string
          enum: [One, Two, Three]
          default: Two

This generates via openapi-generator generate -i openapi.yaml -o out -g aspnetcore -p aspnetVersion=3.0 -Dmodels:

Click to expand
tree out/src/Org.OpenAPITools/Models/
out/src/Org.OpenAPITools/Models/
├── EnumProp.cs
└── Payload.cs

0 directories, 2 files


cat out/src/Org.OpenAPITools/Models/EnumProp.cs
/*
 * API with Default Values
 *
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: 1.0.0
 *
 * Generated by: https://openapi-generator.tech
 */

using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Org.OpenAPITools.Converters;

namespace Org.OpenAPITools.Models
{
        /// <summary>
        /// Gets or Sets EnumProp
        /// </summary>
        [TypeConverter(typeof(CustomEnumConverter<EnumProp>))]
        [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
        public enum EnumProp
        {

            /// <summary>
            /// Enum OneEnum for One
            /// </summary>
            [EnumMember(Value = "One")]
            OneEnum = 1,

            /// <summary>
            /// Enum TwoEnum for Two
            /// </summary>
            [EnumMember(Value = "Two")]
            TwoEnum = 2,

            /// <summary>
            /// Enum ThreeEnum for Three
            /// </summary>
            [EnumMember(Value = "Three")]
            ThreeEnum = 3
        }
}

cat out/src/Org.OpenAPITools/Models/Payload.cs
/*
 * API with Default Values
 *
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: 1.0.0
 *
 * Generated by: https://openapi-generator.tech
 */

using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Org.OpenAPITools.Converters;

namespace Org.OpenAPITools.Models
{
    /// <summary>
    ///
    /// </summary>
    [DataContract]
    public partial class Payload : IEquatable<Payload>
    {
        /// <summary>
        /// Gets or Sets StringProp
        /// </summary>
        [DataMember(Name="stringProp", EmitDefaultValue=false)]
        public string StringProp { get; set; } = "foo";

        /// <summary>
        /// Gets or Sets DoubleProp
        /// </summary>
        [DataMember(Name="doubleProp", EmitDefaultValue=false)]
        public double DoubleProp { get; set; } = 1.234D;

        /// <summary>
        /// Gets or Sets EnumProp
        /// </summary>
        [DataMember(Name="enumProp", EmitDefaultValue=false)]
        public EnumProp EnumProp { get; set; }

        /// <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 Payload {\n");
            sb.Append("  StringProp: ").Append(StringProp).Append("\n");
            sb.Append("  DoubleProp: ").Append(DoubleProp).Append("\n");
            sb.Append("  EnumProp: ").Append(EnumProp).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 string ToJson()
        {
            return JsonConvert.SerializeObject(this, Formatting.Indented);
        }

        /// <summary>
        /// Returns true if objects are equal
        /// </summary>
        /// <param name="obj">Object to be compared</param>
        /// <returns>Boolean</returns>
        public override bool Equals(object obj)
        {
            if (obj is null) return false;
            if (ReferenceEquals(this, obj)) return true;
            return obj.GetType() == GetType() && Equals((Payload)obj);
        }

        /// <summary>
        /// Returns true if Payload instances are equal
        /// </summary>
        /// <param name="other">Instance of Payload to be compared</param>
        /// <returns>Boolean</returns>
        public bool Equals(Payload other)
        {
            if (other is null) return false;
            if (ReferenceEquals(this, other)) return true;

            return
                (
                    StringProp == other.StringProp ||
                    StringProp != null &&
                    StringProp.Equals(other.StringProp)
                ) &&
                (
                    DoubleProp == other.DoubleProp ||

                    DoubleProp.Equals(other.DoubleProp)
                ) &&
                (
                    EnumProp == other.EnumProp ||

                    EnumProp.Equals(other.EnumProp)
                );
        }

        /// <summary>
        /// Gets the hash code
        /// </summary>
        /// <returns>Hash code</returns>
        public override int GetHashCode()
        {
            unchecked // Overflow is fine, just wrap
            {
                var hashCode = 41;
                // Suitable nullity checks etc, of course :)
                    if (StringProp != null)
                    hashCode = hashCode * 59 + StringProp.GetHashCode();

                    hashCode = hashCode * 59 + DoubleProp.GetHashCode();

                    hashCode = hashCode * 59 + EnumProp.GetHashCode();
                return hashCode;
            }
        }

        #region Operators
        #pragma warning disable 1591

        public static bool operator ==(Payload left, Payload right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(Payload left, Payload right)
        {
            return !Equals(left, right);
        }

        #pragma warning restore 1591
        #endregion Operators
    }
}

Given openapi-inline.yaml with enum as inline definition:

openapi: '3.0.0'
info:
  version: 1.0.0
  title: API with Default Values
servers:
  - url: http://localhost:8080
paths:
  /test:
    post:
      operationId: testDefaults
      requestBody:
        required: true
        content:
          application/json:
            schema:
              '$ref': '#/components/schemas/Payload'
      responses:
        '200':
          description: Ok
components:
  schemas:
    Payload:
      type: object
      properties:
        stringProp:
          type: string
          default: foo
        doubleProp:
          type: number
          format: double
          default: 1.234
        enumProp:
          type: string
          enum: [One, Two, Three, Four]
          default: Two

This generates via openapi-generator.local generate -i openapi-inline.yaml -o out-inline -g aspnetcore -p aspnetVersion=3.0 -Dmodels:

Click to expand
tree out-inline/src/Org.OpenAPITools/Models/
out-inline/src/Org.OpenAPITools/Models/
└── Payload.cs

0 directories, 1 file

cat out-inline/src/Org.OpenAPITools/Models/Payload.cs

/*
 * API with Default Values
 *
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: 1.0.0
 *
 * Generated by: https://openapi-generator.tech
 */

using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Org.OpenAPITools.Converters;

namespace Org.OpenAPITools.Models
{
    /// <summary>
    ///
    /// </summary>
    [DataContract]
    public partial class Payload : IEquatable<Payload>
    {
        /// <summary>
        /// Gets or Sets StringProp
        /// </summary>
        [DataMember(Name="stringProp", EmitDefaultValue=false)]
        public string StringProp { get; set; } = "foo";

        /// <summary>
        /// Gets or Sets DoubleProp
        /// </summary>
        [DataMember(Name="doubleProp", EmitDefaultValue=false)]
        public double DoubleProp { get; set; } = 1.234D;


        /// <summary>
        /// Gets or Sets EnumProp
        /// </summary>
        [TypeConverter(typeof(CustomEnumConverter<EnumPropEnum>))]
        [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
        public enum EnumPropEnum
        {

            /// <summary>
            /// Enum OneEnum for One
            /// </summary>
            [EnumMember(Value = "One")]
            OneEnum = 1,

            /// <summary>
            /// Enum TwoEnum for Two
            /// </summary>
            [EnumMember(Value = "Two")]
            TwoEnum = 2,

            /// <summary>
            /// Enum ThreeEnum for Three
            /// </summary>
            [EnumMember(Value = "Three")]
            ThreeEnum = 3,

            /// <summary>
            /// Enum FourEnum for Four
            /// </summary>
            [EnumMember(Value = "Four")]
            FourEnum = 4
        }

        /// <summary>
        /// Gets or Sets EnumProp
        /// </summary>
        [DataMember(Name="enumProp", EmitDefaultValue=false)]
        public EnumPropEnum EnumProp { get; set; } = EnumPropEnum.TwoEnum;

        /// <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 Payload {\n");
            sb.Append("  StringProp: ").Append(StringProp).Append("\n");
            sb.Append("  DoubleProp: ").Append(DoubleProp).Append("\n");
            sb.Append("  EnumProp: ").Append(EnumProp).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 string ToJson()
        {
            return JsonConvert.SerializeObject(this, Formatting.Indented);
        }

        /// <summary>
        /// Returns true if objects are equal
        /// </summary>
        /// <param name="obj">Object to be compared</param>
        /// <returns>Boolean</returns>
        public override bool Equals(object obj)
        {
            if (obj is null) return false;
            if (ReferenceEquals(this, obj)) return true;
            return obj.GetType() == GetType() && Equals((Payload)obj);
        }

        /// <summary>
        /// Returns true if Payload instances are equal
        /// </summary>
        /// <param name="other">Instance of Payload to be compared</param>
        /// <returns>Boolean</returns>
        public bool Equals(Payload other)
        {
            if (other is null) return false;
            if (ReferenceEquals(this, other)) return true;

            return
                (
                    StringProp == other.StringProp ||
                    StringProp != null &&
                    StringProp.Equals(other.StringProp)
                ) &&
                (
                    DoubleProp == other.DoubleProp ||

                    DoubleProp.Equals(other.DoubleProp)
                ) &&
                (
                    EnumProp == other.EnumProp ||

                    EnumProp.Equals(other.EnumProp)
                );
        }

        /// <summary>
        /// Gets the hash code
        /// </summary>
        /// <returns>Hash code</returns>
        public override int GetHashCode()
        {
            unchecked // Overflow is fine, just wrap
            {
                var hashCode = 41;
                // Suitable nullity checks etc, of course :)
                    if (StringProp != null)
                    hashCode = hashCode * 59 + StringProp.GetHashCode();

                    hashCode = hashCode * 59 + DoubleProp.GetHashCode();

                    hashCode = hashCode * 59 + EnumProp.GetHashCode();
                return hashCode;
            }
        }

        #region Operators
        #pragma warning disable 1591

        public static bool operator ==(Payload left, Payload right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(Payload left, Payload right)
        {
            return !Equals(left, right);
        }

        #pragma warning restore 1591
        #endregion Operators
    }
}

PR checklist

  • Read the contribution guidelines.
  • If contributing template-only or documentation-only changes which will change sample output, build the project before.
  • Run the shell script(s) under ./bin/ (or Windows batch scripts under.\bin\windows) to update Petstore samples related to your fix. This is important, as CI jobs will verify all generator outputs of your HEAD commit, and these must match the expectations made by your contribution. You only need to run ./bin/{LANG}-petstore.sh, ./bin/openapi3/{LANG}-petstore.sh if updating the code or mustache templates for a language ({LANG}) (e.g. php, ruby, python, etc).
  • File the PR against the correct branch: master, 4.3.x, 5.0.x. Default: master.
  • Copy the technical committee to review the pull request if your PR is targeting a particular programming language.

cc @binaryunary @OpenAPITools/generator-core-team (we don't have an aspnetcore technical committee)

Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: github/fork/jimschubert/fix-aspnetcore-duplicate-enums