Search code examples
swashbuckleswashbuckle.aspnetcoreautorest

Data does not match any schemas from 'oneOf'


I am getting this error after upgrading my api from .netcore2.2 to 3.1 and trying to generate using autorest with the --v3 switch

WARNING: Schema violation: Data does not match any schemas from 'oneOf'

I have tried with and without SerializeAsV2

I see from the Autorest docs that this warning is because of an supported feature.

anyOf, oneOf are not currently supported

In services.AddSwaggerGen I have

            c.ParameterFilter<SwaggerEnumParameterFilter>();
            c.SchemaFilter<SwaggerEnumFilter>();

where

public void Apply(OpenApiParameter parameter, ParameterFilterContext context)
{
    var type = context.ApiParameterDescription.Type;

    if (type.IsEnum)
        parameter.Extensions.Add("x-ms-enum", new OpenApiObject
        {
            ["name"] = new OpenApiString(type.Name),
            ["modelAsString"] = new OpenApiBoolean(false)
        });
     
}

public class SwaggerEnumFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema model, SchemaFilterContext context)
    {
        if (model == null)
            throw new ArgumentNullException("model");
        if (context == null)
            throw new ArgumentNullException("context");
        if (context.Type.IsEnum)
            model.Extensions.Add(
                "x-ms-enum",
                new OpenApiObject
                {
                    ["name"] = new OpenApiString(context.Type.Name),
                    ["modelAsString"] = new OpenApiBoolean(false)
                }
            );
    }
}

[update]

After upgrading to Autorest 3.0.6244 the warnings have changed to errors and the error message ends with

post > parameters > 0)

If I don't use the v3 switch I get the error

FATAL: swagger-document/individual/schema-validator - FAILED
FATAL: Error: [OperationAbortedException] Error occurred. Exiting.
Process() cancelled due to exception : [OperationAbortedException] Error occurred. Exiting.

I can see in the swagger.json that the parameters property "name" is not generating correctly. Here it contains "body" whereas previously it contained "info"

"/api/FrameLookUp": {
    "post": {
        "tags": [
            "Frame"
        ],
        "operationId": "FrameLookup",
        "consumes": [
            "application/json-patch+json",
            "application/json",
            "text/json",
            "application/*+json"
        ],
        "produces": [
            "application/json"
        ],
        "parameters": [
            {
                "in": "header",
                "name": "Authorization",
                "description": "access token",
                "required": true,
                "type": "String"
            },
            {
                "in": "body", 
                "name": "body",
                "schema": {
                    "$ref": "#/definitions/FrameRequest"
                }
            }
        ],
        "responses": {
            "200": {
                "description": "Success",
                "schema": {
                    "$ref": "#/definitions/FrameResponse"
                }
            }
        }
    }
},

The controller is

[Produces("application/json")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api")]

public class FrameController : MyController
{
    [ProducesResponseType(typeof(FrameResponse), StatusCodes.Status200OK)]
    [HttpPost("FrameLookUp")]
    public IActionResult FrameLookup([FromBody] FrameRequest  info)
    {
        IMyResponse MyFunc(IMyRequest x) => FrameData.FrameLookUp(info);
        return InnerMethod(MyFunc, info);
    }
 }

Update

I have also tried using the SwaggerParameter from Swashbuckle.AspNetCore.Annotations

[Update]

I am thinking that maybe I just need to try the release for issue 1766

I tried cloning the swashbuckle.aspnetcore repo but ran into this issue

[Update]

I added c.GeneratePolymorphicSchemas(); to the AddSwaggerGen options but it has not helped.

[Update] Here is the first error message

ERROR: Schema violation: Data does not match any schemas from 'oneOf'
    - https://localhost:44348/api-docs/v1/swagger.json:1951:8 ($.paths["/api/synchronise-management/get-product-images-Ids"].post.parameters)

Investigating line 1951 in swagger.json

line which causes error

In the working swagger ( generated from dotnet2.2 project ) the json looks very similar however the parameter order is swapped working json

The other difference I can see is the generated name of the parameter

I see from this question the error occurs in the same place

[Update] when I add the --debug switch to the autorest call I get

/configuration
DEBUG: pipeline-emitter - END
DEBUG: configuration-emitter - END
DEBUG: swagger-document-override/md-override-loader - END
DEBUG: swagger-document/loader - END
DEBUG: swagger-document/individual/transform - START
DEBUG: swagger-document/individual/transform - END
DEBUG: swagger-document/individual/schema-validator - START
ERROR: Schema violation: Data does not match any schemas from 'oneOf'
    - https://localhost:44348/api/v1/swagger.json:1951:8 ($.paths["/api/synchronise-management/get-product-images-Ids"].

[Update]

Here is the cut down json

{
    "swagger": "2.0",
    "info": {
        "title": "myapi API31",
        "description": "ASP.NET Core Web API",
        "version": "v1"
    },
    "host": "localhost:44348",
    "basePath": "/v1",
    "schemes": [
        "https"
    ],
    "paths": {
        "/api/Test": {
            "get": {
                "tags": [
                    "Auth"
                ],
                "operationId": "Test",
                "responses": {
                    "200": {
                        "description": "Success"
                    }
                }
            }
        },
        "/api/RequestToken": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "operationId": "RequestToken",
                "consumes": [
                    "application/json-patch+json",
                    "application/json",
                    "text/json",
                    "application/*+json"
                ],
                "produces": [
                    "application/json"
                ],
                "parameters": [
                    {
                        "in": "body",
                        "name": "body",
                        "schema": {
                            "$ref": "#/definitions/TokenRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "schema": {
                            "$ref": "#/definitions/TokenResponse"
                        }
                    }
                }
            }
        },
        "/api/FrameLookUp": {
            "post": {
                "tags": [
                    "Frame"
                ],
                "operationId": "FrameLookup",
                "consumes": [
                    "application/json-patch+json",
                    "application/json",
                    "text/json",
                    "application/*+json"
                ],
                "produces": [
                    "application/json"
                ],
                "parameters": [
                    {
                        "in": "header",
                        "name": "Authorization",
                        "description": "access token",
                        "required": true,
                        "type": "String"
                    },
                    {
                        "in": "body",
                        "name": "body",
                        "schema": {
                            "$ref": "#/definitions/FrameRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "schema": {
                            "$ref": "#/definitions/FrameResponse"
                        }
                    }
                }
            }
        } 
    },
    "definitions": {
        "TokenRequest": {
            "required": [
                "password",
                "username"
            ],
            "type": "object",
            "properties": {
                "username": {
                    "type": "string"
                },
                "password": {
                    "type": "string"
                }
            }
        },
        "TokenResponse": {
            "type": "object",
            "properties": {
                "tokenResult": {
                    "type": "string"
                }
            }
        },
        "FramePackTypeEnum": {
            "enum": [
                "NotApplicable",
                "PipeRack",
                "LwBVan",
                "VanTray",
                "Car",
                "CarryBag"
            ],
            "type": "string",
            "x-ms-enum": {
                "name": "FramePackTypeEnum",
                "modelAsString": false
            }
        },
        "FrameRequest": {
            "type": "object",
            "properties": {
                "qCodeJobId": {
                    "format": "int32",
                    "type": "integer"
                },
                "quantity": {
                    "format": "int32",
                    "type": "integer"
                },
                "widthInMm": {
                    "format": "int32",
                    "type": "integer"
                },
                "heightInMm": {
                    "format": "int32",
                    "type": "integer"
                },
                "ePackingType": {
                    "$ref": "#/definitions/FramePackTypeEnum"
                },
                "userEmail": {
                    "type": "string"
                }
            }
        },
        "FrameCaseEnum": {
            "enum": [
                "Case0_NoBraces",
                "Case1_1Vertical_0Horizontal",
                "Case2_2Vertical_0Horizontal",
                "Case3_NVertical_0Horizontal",
                "Case4_0Vertical_1Horizontal",
                "Case5_1Vertical_1Horizontal",
                "Case6_2Vertical_1Horizontal",
                "Case7_NVertical_1Horizontal",
                "Case8_0Vertical_2Horizontal",
                "Case9_1Vertical_2Horizontal",
                "Case10_2Vertical_2Horizontal",
                "Case11_NVertical_2Horizontal",
                "Case12_0Vertical_NHorizontal",
                "Case13_1Vertical_NHorizontal",
                "Case14_2Vertical_NHorizontal",
                "Case15_NVertical_NHorizontal"
            ],
            "type": "string",
            "x-ms-enum": {
                "name": "FrameCaseEnum",
                "modelAsString": false
            }
        },
        "FrameResponse": {
            "type": "object",
            "properties": {
                "description": {
                    "type": "string"
                },
                "caseNumber": {
                    "$ref": "#/definitions/FrameCaseEnum"
                },
                "memberPriceEachExGst": {
                    "format": "double",
                    "type": "number"
                },
                "retailPriceEachExGst": {
                    "format": "double",
                    "type": "number"
                }
            }
        }
    }
}

With the .netcore2.2 api the request generates as

"FrameRequest": {
    "type": "object",
    "properties": {
        "qCodeJobId": {
            "format": "int32",
            "type": "integer"
        },
        "quantity": {
            "format": "int32",
            "type": "integer"
        },
        "widthInMm": {
            "format": "int32",
            "type": "integer"
        },
        "heightInMm": {
            "format": "int32",
            "type": "integer"
        },
        "ePackingType": {
            "enum": [
                "NotApplicable",
                "PipeRack",
                "LwBVan",
                "VanTray",
                "Car",
                "CarryBag"
            ],
            "type": "string",
            "x-ms-enum": {
                "name": "FramePackTypeEnum",
                "modelAsString": false
            }
        },
        "userEmail": {
            "type": "string"
        }
    }
}

Here is the command line I am running

autorest --input-file=.\myswagger.json --output-folder=generated --csharp --namespace=DDD --debug

Some links which the author, Kirsten Greed, put in comments:


Solution

  • From your swagger.json we can see the validation shows:
    https://validator.swagger.io/validator/debug?url=https://raw.githubusercontent.com/heldersepu/hs-scripts/master/swagger/63783800_swagger.json

    {
    "schemaValidationMessages": [
    {
      "level": "error",
      "domain": "validation",
      "keyword": "oneOf",
      "message": "instance failed to match exactly one schema (matched 0 out of 2)",
      "schema": {
        "loadingURI": "http://swagger.io/v2/schema.json#",
        "pointer": "/definitions/parametersList/items"
      },
      "instance": {
        "pointer": "/paths/~1api~1FrameLookUp/post/parameters/0"
      }
    }
    ]
    }
    

    that lead us to your code:

    that type: "String" should be: type: "string" with all lower case the error goes away