1

我正在使用Autorest从 swagger 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属性以公开其附加属性。MetaMetaResponseExtended

例如,我想要的输出是:

public partial class MyResourceResponseExtended : MyResourceResponse
{
    [JsonProperty(PropertyName = "meta")]
    public new ExtendedMetaResponse Meta { get; set; }

    public MyResourceResponseExtended(ExtendedMetaResponse meta)
        : base(meta)
    {
        Meta = meta;
        CustomInit();
    }
}

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

谢谢!:-)

PS:我已经研究discriminator过在 swagger 文件中使用,但我要么没有正确使用它,要么它不是为这个特定目的而设计的。

4

1 回答 1

1

您肯定需要使用 a discriminator,并从中创建一个多态类型。

为了拥有多态类型,您必须拥有一个声明为 a 的属性,discriminator并且作为父类的子类(即 using 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# 中,它会为此使用类上的属性。)

于 2019-07-01T19:57:14.047 回答