Autorest无法覆盖子类中的父级属性

时间:2019-07-01 19:07:29

标签: polymorphism swagger-2.0 autorest

我正在使用Autorest从不拘一格的2.0定义生成一个csharp sdk,我想知道是否有可能使生成的子类覆盖具有不同类型的父级属性。

招摇示例:

{
    "swagger": "2.0",
    "info": {
        "version": "1",
        "title": "My API"
    },
    "schemes": [
        "https"
    ],
    "consumes": [
        "application/json"
    ],
    "produces": [
        "application/json"
    ],
    "paths": {
        "/myResource": {
            "post": {
                "parameters": [
                    {
                        "name": "myResource_data",
                        "in": "body",
                        "schema": {
                            "$ref": "#/definitions/myResourceCreateBody"
                        },
                        "required": true
                    }
                ],
                "responses": {
                    "201": {
                        "description": "myResource response",
                        "schema": {
                            "$ref": "#/definitions/myResourceResponseExtended"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "metaResponse": {
            "type": "object",
            "description": "Response metadata.",
            "required": [
                "api_version"
            ],
            "properties": {
                "api_version": {
                    "type": "string"
                }
            },
            "x-services": [
                "shared"
            ]
        },
        "extendedMetaResponse": {
            "allOf": [
                {
                    "$ref": "#/definitions/metaResponse"
                },
                {
                    "type": "object",
                    "properties": {
                        "myExtendedProp": {
                            "type": "string"
                        }
                    }
                }
            ],
            "x-services": [
                "shared"
            ]
        },
        "myResourceResponse": {
            "type": "object",
            "required": [
                "meta"
            ],
            "additionalProperties": false,
            "properties": {
                "meta": {
                    "$ref": "#/definitions/metaResponse"
                }
            },
            "x-services": [
                "myResource"
            ]
        },
        "myResourceResponseExtended": {
            "allOf": [
                {
                    "$ref": "#/definitions/myResourceResponse"
                },
                {
                    "type": "object",
                    "properties": {
                        "meta": {
                            "$ref": "#/definitions/extendedMetaResponse"
                        }
                    }
                }
            ],
            "x-services": [
                "myResource"
            ]
        },
        "myResourceCreateBody": {
            "type": "object",
            "required": [
                "myResource_id"
            ],
            "additionalProperties": false,
            "properties": {
                "myResource_id": {
                    "type": "string",
                    "description": "myResource identifier"
                }
            },
            "x-services": [
                "myResource"
            ]
        }
    }
}

哪个生成以下C#基类:

    public partial class MyResourceResponse
    {
        public MyResourceResponse()
        {
            CustomInit();
        }

        public MyResourceResponse(MetaResponse meta)
        {
            Meta = meta;
            CustomInit();
        }

        partial void CustomInit();

        [JsonProperty(PropertyName = "meta")]
        public MetaResponse Meta { get; set; }

        public virtual void Validate()
        {
            if (Meta == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "Meta");
            }
            if (Meta != null)
            {
                Meta.Validate();
            }
        }
    }
}

以及以下子类:

    public partial class MyResourceResponseExtended : MyResourceResponse
    {
        public MyResourceResponseExtended()
        {
            CustomInit();
        }

        public MyResourceResponseExtended(MetaResponse meta)
            : base(meta)
        {
            CustomInit();
        }

        partial void CustomInit();

        public override void Validate()
        {
            base.Validate();
        }
    }

但是我想要的输出是让MyResourceResponseExtended用类型为Meta的{​​{1}}属性覆盖Meta属性,以显示其附加属性。

例如,我想要的输出将是:

MetaResponseExtended

在Swagger 2.0中是否有更好的方法来定义它? 这是Autorest的错误/局限性吗?

谢谢! :-)

PS:我曾经考虑过在swagger文件中使用public partial class MyResourceResponseExtended : MyResourceResponse { [JsonProperty(PropertyName = "meta")] public new ExtendedMetaResponse Meta { get; set; } public MyResourceResponseExtended(ExtendedMetaResponse meta) : base(meta) { Meta = meta; CustomInit(); } } ,但是我没有正确使用它,或者它不是专门为该特定目的而设计的。

1 个答案:

答案 0 :(得分:1)

您肯定需要使用discriminator,并使用它来创建多态类型。

要具有多态类型,必须具有一个声明为discriminator的属性,并且作为父类的子级(即,使用allOf)的每种类型都必须具有x-ms-discriminator-value,它可以用作密钥来允许反序列化器选择要反序列化为的正确类型。

简单的例子:

swagger: '2.0'
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
host: petstore.swagger.io
basePath: "/v1"
schemes:
- https
consumes:
- application/json
produces:
- application/json
paths:
  "/pets":
    put:
      summary: Add a pet
      operationId: addPet
      tags:
      - pets
      parameters:
      - schema:
          "$ref": "#/definitions/Pet"
      responses:
        '200':
          description: OK
definitions:
  Pet:
    properties:
      petKind:
        type: string
      name:
        type: string
    discriminator: petKind
    required:
    - name
    - petType
  Cat:
    description: A representation of a cat
    x-ms-discriminator-value: CAT
    allOf:
    - "$ref": "#/definitions/Pet"
    - properties:
        huntingSkill:
          type: string
          description: The measured skill for hunting
          default: lazy
          enum:
          - clueless
          - lazy
          - adventurous
          - aggressive
      required:
      - huntingSkill
  Dog:
    description: A representation of a dog
    x-ms-discriminator-value: DOG
    allOf:
    - "$ref": "#/definitions/Pet"
    - properties:
        packSize:
          type: integer
          format: int32
          description: the size of the pack the dog is from
          default: 0
          minimum: 0
      required:
      - packSize

Pet对象具有petKind属性(DOGCAT),该属性告诉反序列化器使用哪种模型反序列化值。

(在生成的c#中,它将为此使用类的属性。)