diff --git a/Directory.Packages.props b/Directory.Packages.props
index 9e100ec035..a3b73e2eb2 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -2,35 +2,35 @@
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
-
-
+
+
+
+
diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/JsonSerializerDataContractResolver.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/JsonSerializerDataContractResolver.cs
index c048d970ed..3e2a6404aa 100644
--- a/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/JsonSerializerDataContractResolver.cs
+++ b/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/JsonSerializerDataContractResolver.cs
@@ -96,7 +96,7 @@ public DataContract GetDataContractForType(Type type)
return DataContract.ForObject(
underlyingType: effectiveType,
- properties: GetDataPropertiesFor(type, out Type extensionDataType),
+ properties: GetDataPropertiesFor(effectiveType, out Type extensionDataType),
extensionDataType: extensionDataType,
jsonConverter: (value) => JsonConverterFunc(value, effectiveType));
}
diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_Basic_DotNet_6.verified.txt b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_Basic_DotNet_6.verified.txt
new file mode 100644
index 0000000000..ce88e0c243
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_Basic_DotNet_6.verified.txt
@@ -0,0 +1,1502 @@
+{
+ openapi: 3.0.1,
+ info: {
+ title: Test API V1,
+ description: A sample API for testing Swashbuckle,
+ termsOfService: http://tempuri.org/terms,
+ version: v1
+ },
+ paths: {
+ /products: {
+ post: {
+ tags: [
+ CrudActions
+ ],
+ summary: Creates a product,
+ description:
+## Heading 1
+
+ POST /products
+ {
+ "id": "123",
+ "description": "Some product"
+ },
+ operationId: CreateProduct,
+ requestBody: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ }
+ },
+ required: true,
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ get: {
+ tags: [
+ CrudActions
+ ],
+ summary: Searches the collection of products by description key words,
+ operationId: SearchProducts,
+ parameters: [
+ {
+ name: kw,
+ in: query,
+ description: A list of search terms,
+ schema: {
+ type: string,
+ default: foobar
+ },
+ example: hello
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/Product
+ }
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /products/{id}: {
+ get: {
+ tags: [
+ CrudActions
+ ],
+ summary: Returns a specific product,
+ operationId: GetProduct,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: The product id,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ },
+ example: 111
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ put: {
+ tags: [
+ CrudActions
+ ],
+ summary: Updates all properties of a specific product,
+ operationId: UpdateProduct,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: ,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ },
+ example: 222
+ }
+ ],
+ requestBody: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ }
+ },
+ required: true,
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ },
+ patch: {
+ tags: [
+ CrudActions
+ ],
+ summary: Updates some properties of a specific product,
+ operationId: PatchProduct,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: ,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ },
+ example: 333
+ }
+ ],
+ requestBody: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ type: object
+ }
+ },
+ text/json: {
+ schema: {
+ type: object
+ }
+ },
+ application/*+json: {
+ schema: {
+ type: object
+ }
+ }
+ },
+ required: true,
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ },
+ delete: {
+ tags: [
+ CrudActions
+ ],
+ summary: Deletes a specific product,
+ operationId: DeleteProduct,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: ,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ },
+ example: 444
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /payments/authorize: {
+ post: {
+ tags: [
+ DataAnnotations
+ ],
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/PaymentRequest
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/PaymentRequest
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/PaymentRequest
+ }
+ }
+ },
+ required: true,
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: string
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /payments/{paymentId}/cancel: {
+ put: {
+ tags: [
+ DataAnnotations
+ ],
+ parameters: [
+ {
+ name: paymentId,
+ in: path,
+ required: true,
+ schema: {
+ minLength: 6,
+ type: string
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /kittens: {
+ post: {
+ tags: [
+ DynamicTypes
+ ],
+ requestBody: {
+ content: {
+ application/json: {},
+ text/json: {},
+ application/*+json: {}
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /unicorns: {
+ get: {
+ tags: [
+ DynamicTypes
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: object
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /dragons: {
+ post: {
+ tags: [
+ DynamicTypes
+ ],
+ requestBody: {
+ content: {
+ application/json: {},
+ text/json: {},
+ application/*+json: {}
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /files/single: {
+ post: {
+ tags: [
+ Files
+ ],
+ requestBody: {
+ content: {
+ multipart/form-data: {
+ schema: {
+ type: object,
+ properties: {
+ file: {
+ type: string,
+ format: binary
+ }
+ }
+ },
+ encoding: {
+ file: {
+ style: form
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /files/multiple: {
+ post: {
+ tags: [
+ Files
+ ],
+ requestBody: {
+ content: {
+ multipart/form-data: {
+ schema: {
+ type: object,
+ properties: {
+ files: {
+ type: array,
+ items: {
+ type: string,
+ format: binary
+ }
+ }
+ }
+ },
+ encoding: {
+ files: {
+ style: form
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /files/form-with-file: {
+ post: {
+ tags: [
+ Files
+ ],
+ requestBody: {
+ content: {
+ multipart/form-data: {
+ schema: {
+ type: object,
+ properties: {
+ name: {
+ type: string
+ },
+ file: {
+ type: string,
+ format: binary
+ }
+ }
+ },
+ encoding: {
+ name: {
+ style: form
+ },
+ file: {
+ style: form
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /files/{name}: {
+ get: {
+ tags: [
+ Files
+ ],
+ parameters: [
+ {
+ name: name,
+ in: path,
+ required: true,
+ schema: {
+ type: string
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ text/plain: {
+ schema: {
+ oneOf: [
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ }
+ ]
+ }
+ },
+ application/zip: {
+ schema: {
+ oneOf: [
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /registrations: {
+ post: {
+ tags: [
+ FromFormParams
+ ],
+ requestBody: {
+ content: {
+ application/x-www-form-urlencoded: {
+ schema: {
+ type: object,
+ properties: {
+ name: {
+ type: string
+ },
+ phoneNumbers: {
+ type: array,
+ items: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ },
+ encoding: {
+ name: {
+ style: form
+ },
+ phoneNumbers: {
+ style: form
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /registrationsWithIgnoreProperties: {
+ post: {
+ tags: [
+ FromFormParams
+ ],
+ requestBody: {
+ content: {
+ multipart/form-data: {
+ schema: {
+ type: object,
+ properties: {
+ phoneNumbers: {
+ type: array,
+ items: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ },
+ encoding: {
+ phoneNumbers: {
+ style: form
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /country/validate: {
+ get: {
+ tags: [
+ FromHeaderParams
+ ],
+ parameters: [
+ {
+ name: country,
+ in: query,
+ schema: {
+ type: string
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /addresses/validate: {
+ get: {
+ tags: [
+ FromQueryParams
+ ],
+ parameters: [
+ {
+ name: country,
+ in: query,
+ description: 3-letter ISO country code,
+ required: true,
+ schema: {
+ type: string
+ }
+ },
+ {
+ name: city,
+ in: query,
+ description: Name of city,
+ schema: {
+ type: string,
+ default: Seattle
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /zip-codes/validate: {
+ get: {
+ tags: [
+ FromQueryParams
+ ],
+ parameters: [
+ {
+ name: zipCodes,
+ in: query,
+ schema: {
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /Issue3013/Get: {
+ get: {
+ tags: [
+ Issue3013
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ text/plain: {
+ schema: {
+ $ref: #/components/schemas/TestResponse
+ }
+ },
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/TestResponse
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/TestResponse
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /promotions: {
+ get: {
+ tags: [
+ JsonAnnotations
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/Promotion
+ }
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /shapes: {
+ post: {
+ tags: [
+ PolymorphicTypes
+ ],
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ oneOf: [
+ null,
+ null
+ ]
+ }
+ },
+ text/json: {
+ schema: {
+ oneOf: [
+ null,
+ null
+ ]
+ }
+ },
+ application/*+json: {
+ schema: {
+ oneOf: [
+ null,
+ null
+ ]
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ text/plain: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ },
+ application/json: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ },
+ text/json: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /orders: {
+ post: {
+ tags: [
+ ResponseTypeAnnotations
+ ],
+ summary: Creates an order,
+ requestBody: {
+ description: ,
+ content: {
+ application/xml: {
+ schema: {
+ $ref: #/components/schemas/Order
+ }
+ }
+ },
+ required: true,
+ x-purpose: test
+ },
+ responses: {
+ 201: {
+ description: Order created,
+ content: {
+ application/xml: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ },
+ 400: {
+ description: Order invalid,
+ content: {
+ application/xml: {
+ schema: {
+ $ref: #/components/schemas/ValidationProblemDetails
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /carts: {
+ post: {
+ tags: [
+ SwaggerAnnotations
+ ],
+ operationId: CreateCart,
+ requestBody: {
+ description: The cart request body,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 201: {
+ description: The cart was created,
+ content: {
+ text/plain: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ }
+ }
+ },
+ 400: {
+ description: The cart data is invalid
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /carts/{id}: {
+ get: {
+ tags: [
+ SwaggerAnnotations
+ ],
+ externalDocs: {
+ description: External docs for CartsByIdGet,
+ url: https://tempuri.org/carts-by-id-get
+ },
+ operationId: GetCart,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: The cart identifier,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ text/plain: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ delete: {
+ tags: [
+ SwaggerAnnotations
+ ],
+ summary: Deletes a specific cart,
+ description: Requires admin privileges,
+ operationId: DeleteCart,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: The cart identifier,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ text/plain: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /stores: {
+ post: {
+ tags: [
+ UnboundParams
+ ],
+ parameters: [
+ {
+ name: id,
+ in: query,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ },
+ {
+ name: location,
+ in: query,
+ schema: {
+ type: string
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ get: {
+ tags: [
+ UnboundParams
+ ],
+ parameters: [
+ {
+ name: locations,
+ in: query,
+ schema: {
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/Store
+ }
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /stores/{id}: {
+ get: {
+ tags: [
+ UnboundParams
+ ],
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Store
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ put: {
+ tags: [
+ UnboundParams
+ ],
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ },
+ {
+ name: id,
+ in: query,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ },
+ {
+ name: location,
+ in: query,
+ schema: {
+ type: string
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ },
+ delete: {
+ tags: [
+ UnboundParams
+ ],
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ }
+ },
+ components: {
+ schemas: {
+ Cart: {
+ required: [
+ Id
+ ],
+ type: object,
+ properties: {
+ id: {
+ type: integer,
+ description: The cart identifier,
+ format: int32,
+ readOnly: true
+ },
+ cartType: {
+ $ref: #/components/schemas/CartType
+ }
+ },
+ additionalProperties: false
+ },
+ CartType: {
+ enum: [
+ 0,
+ 1
+ ],
+ type: integer,
+ description: The cart type,
+ format: int32
+ },
+ Circle: {
+ allOf: [
+ null,
+ {
+ type: object,
+ properties: {
+ radius: {
+ type: integer,
+ format: int32
+ }
+ },
+ additionalProperties: false
+ }
+ ]
+ },
+ CreditCard: {
+ required: [
+ cardNumber,
+ expMonth,
+ expYear
+ ],
+ type: object,
+ properties: {
+ cardNumber: {
+ minLength: 1,
+ pattern: ^[3-6]?\d{12,15}$,
+ type: string
+ },
+ expMonth: {
+ maximum: 12,
+ minimum: 1,
+ type: integer,
+ format: int32
+ },
+ expYear: {
+ maximum: 99,
+ minimum: 14,
+ type: integer,
+ format: int32
+ }
+ },
+ additionalProperties: false
+ },
+ DiscountType: {
+ enum: [
+ Percentage,
+ Amount
+ ],
+ type: string
+ },
+ Order: {
+ type: object,
+ properties: {
+ id: {
+ type: integer,
+ format: int32
+ },
+ description: {
+ type: string,
+ nullable: true
+ },
+ total: {
+ type: number,
+ format: double
+ }
+ },
+ additionalProperties: false
+ },
+ PaymentRequest: {
+ required: [
+ creditCard,
+ transaction
+ ],
+ type: object,
+ properties: {
+ transaction: {
+ $ref: #/components/schemas/Transaction
+ },
+ creditCard: {
+ $ref: #/components/schemas/CreditCard
+ }
+ },
+ additionalProperties: false
+ },
+ Product: {
+ type: object,
+ properties: {
+ id: {
+ type: integer,
+ description: Uniquely identifies the product,
+ format: int32
+ },
+ description: {
+ type: string,
+ description: Describes the product,
+ nullable: true
+ },
+ status: {
+ $ref: #/components/schemas/ProductStatus
+ },
+ status2: {
+ $ref: #/components/schemas/ProductStatus
+ }
+ },
+ additionalProperties: false,
+ description: Represents a product,
+ example: {
+ id: 123,
+ description: foobar,
+ price: 14.37
+ }
+ },
+ ProductStatus: {
+ enum: [
+ 0,
+ 1,
+ 2
+ ],
+ type: integer,
+ format: int32
+ },
+ Promotion: {
+ type: object,
+ properties: {
+ promo-code: {
+ type: string,
+ nullable: true
+ },
+ discountType: {
+ $ref: #/components/schemas/DiscountType
+ }
+ },
+ additionalProperties: false
+ },
+ Rectangle: {
+ allOf: [
+ null,
+ {
+ type: object,
+ properties: {
+ height: {
+ type: integer,
+ format: int32
+ },
+ width: {
+ type: integer,
+ format: int32
+ }
+ },
+ additionalProperties: false
+ }
+ ]
+ },
+ Shape: {
+ required: [
+ TypeName
+ ],
+ type: object,
+ properties: {
+ TypeName: {
+ type: string
+ },
+ name: {
+ type: string,
+ nullable: true
+ }
+ },
+ additionalProperties: false,
+ discriminator: {
+ propertyName: TypeName,
+ mapping: {
+ Rectangle: #/components/schemas/Rectangle,
+ Circle: #/components/schemas/Circle
+ }
+ }
+ },
+ Store: {
+ type: object,
+ properties: {
+ id: {
+ type: integer,
+ format: int32
+ },
+ location: {
+ type: string,
+ nullable: true
+ }
+ },
+ additionalProperties: false
+ },
+ TestResponse: {
+ type: object,
+ properties: {
+ foo: {
+ $ref: #/components/schemas/TestStruct
+ }
+ },
+ additionalProperties: false
+ },
+ TestStruct: {
+ type: object,
+ properties: {
+ a: {
+ type: integer,
+ format: int32
+ },
+ b: {
+ type: integer,
+ format: int32
+ }
+ },
+ additionalProperties: false
+ },
+ Transaction: {
+ required: [
+ amount
+ ],
+ type: object,
+ properties: {
+ amount: {
+ type: number,
+ format: double
+ },
+ note: {
+ type: string,
+ nullable: true
+ }
+ },
+ additionalProperties: false
+ },
+ ValidationProblemDetails: {
+ type: object,
+ properties: {
+ type: {
+ type: string,
+ nullable: true
+ },
+ title: {
+ type: string,
+ nullable: true
+ },
+ status: {
+ type: integer,
+ format: int32,
+ nullable: true
+ },
+ detail: {
+ type: string,
+ nullable: true
+ },
+ instance: {
+ type: string,
+ nullable: true
+ },
+ errors: {
+ type: object,
+ additionalProperties: {
+ type: array,
+ items: {
+ type: string
+ }
+ },
+ nullable: true,
+ readOnly: true
+ }
+ }
+ }
+ }
+ },
+ tags: [
+ {
+ name: SwaggerAnnotations,
+ description: Manipulate Carts to your heart's content,
+ externalDocs: {
+ url: http://www.tempuri.org
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_Basic_DotNet_8.verified.txt b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_Basic_DotNet_8.verified.txt
new file mode 100644
index 0000000000..fbae1d65df
--- /dev/null
+++ b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_Basic_DotNet_8.verified.txt
@@ -0,0 +1,1501 @@
+{
+ openapi: 3.0.1,
+ info: {
+ title: Test API V1,
+ description: A sample API for testing Swashbuckle,
+ termsOfService: http://tempuri.org/terms,
+ version: v1
+ },
+ paths: {
+ /products: {
+ post: {
+ tags: [
+ CrudActions
+ ],
+ summary: Creates a product,
+ description:
+## Heading 1
+
+ POST /products
+ {
+ "id": "123",
+ "description": "Some product"
+ },
+ operationId: CreateProduct,
+ requestBody: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ }
+ },
+ required: true,
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ get: {
+ tags: [
+ CrudActions
+ ],
+ summary: Searches the collection of products by description key words,
+ operationId: SearchProducts,
+ parameters: [
+ {
+ name: kw,
+ in: query,
+ description: A list of search terms,
+ schema: {
+ type: string,
+ default: foobar
+ },
+ example: hello
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/Product
+ }
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /products/{id}: {
+ get: {
+ tags: [
+ CrudActions
+ ],
+ summary: Returns a specific product,
+ operationId: GetProduct,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: The product id,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ },
+ example: 111
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ put: {
+ tags: [
+ CrudActions
+ ],
+ summary: Updates all properties of a specific product,
+ operationId: UpdateProduct,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: ,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ },
+ example: 222
+ }
+ ],
+ requestBody: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/Product
+ }
+ }
+ },
+ required: true,
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ },
+ patch: {
+ tags: [
+ CrudActions
+ ],
+ summary: Updates some properties of a specific product,
+ operationId: PatchProduct,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: ,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ },
+ example: 333
+ }
+ ],
+ requestBody: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ type: object
+ }
+ },
+ text/json: {
+ schema: {
+ type: object
+ }
+ },
+ application/*+json: {
+ schema: {
+ type: object
+ }
+ }
+ },
+ required: true,
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ },
+ delete: {
+ tags: [
+ CrudActions
+ ],
+ summary: Deletes a specific product,
+ operationId: DeleteProduct,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: ,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ },
+ example: 444
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /payments/authorize: {
+ post: {
+ tags: [
+ DataAnnotations
+ ],
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/PaymentRequest
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/PaymentRequest
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/PaymentRequest
+ }
+ }
+ },
+ required: true,
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: string
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /payments/{paymentId}/cancel: {
+ put: {
+ tags: [
+ DataAnnotations
+ ],
+ parameters: [
+ {
+ name: paymentId,
+ in: path,
+ required: true,
+ schema: {
+ minLength: 6,
+ type: string
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /kittens: {
+ post: {
+ tags: [
+ DynamicTypes
+ ],
+ requestBody: {
+ content: {
+ application/json: {},
+ text/json: {},
+ application/*+json: {}
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /unicorns: {
+ get: {
+ tags: [
+ DynamicTypes
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: object
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /dragons: {
+ post: {
+ tags: [
+ DynamicTypes
+ ],
+ requestBody: {
+ content: {
+ application/json: {},
+ text/json: {},
+ application/*+json: {}
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /files/single: {
+ post: {
+ tags: [
+ Files
+ ],
+ requestBody: {
+ content: {
+ multipart/form-data: {
+ schema: {
+ type: object,
+ properties: {
+ file: {
+ type: string,
+ format: binary
+ }
+ }
+ },
+ encoding: {
+ file: {
+ style: form
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /files/multiple: {
+ post: {
+ tags: [
+ Files
+ ],
+ requestBody: {
+ content: {
+ multipart/form-data: {
+ schema: {
+ type: object,
+ properties: {
+ files: {
+ type: array,
+ items: {
+ type: string,
+ format: binary
+ }
+ }
+ }
+ },
+ encoding: {
+ files: {
+ style: form
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /files/form-with-file: {
+ post: {
+ tags: [
+ Files
+ ],
+ requestBody: {
+ content: {
+ multipart/form-data: {
+ schema: {
+ type: object,
+ properties: {
+ name: {
+ type: string
+ },
+ file: {
+ type: string,
+ format: binary
+ }
+ }
+ },
+ encoding: {
+ name: {
+ style: form
+ },
+ file: {
+ style: form
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /files/{name}: {
+ get: {
+ tags: [
+ Files
+ ],
+ parameters: [
+ {
+ name: name,
+ in: path,
+ required: true,
+ schema: {
+ type: string
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ text/plain: {
+ schema: {
+ oneOf: [
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ }
+ ]
+ }
+ },
+ application/zip: {
+ schema: {
+ oneOf: [
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ },
+ {
+ type: string,
+ format: binary
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /registrations: {
+ post: {
+ tags: [
+ FromFormParams
+ ],
+ requestBody: {
+ content: {
+ application/x-www-form-urlencoded: {
+ schema: {
+ type: object,
+ properties: {
+ name: {
+ type: string
+ },
+ phoneNumbers: {
+ type: array,
+ items: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ },
+ encoding: {
+ name: {
+ style: form
+ },
+ phoneNumbers: {
+ style: form
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /registrationsWithIgnoreProperties: {
+ post: {
+ tags: [
+ FromFormParams
+ ],
+ requestBody: {
+ content: {
+ multipart/form-data: {
+ schema: {
+ type: object,
+ properties: {
+ phoneNumbers: {
+ type: array,
+ items: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ },
+ encoding: {
+ phoneNumbers: {
+ style: form
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /country/validate: {
+ get: {
+ tags: [
+ FromHeaderParams
+ ],
+ parameters: [
+ {
+ name: country,
+ in: query,
+ schema: {
+ type: string
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /addresses/validate: {
+ get: {
+ tags: [
+ FromQueryParams
+ ],
+ parameters: [
+ {
+ name: country,
+ in: query,
+ description: 3-letter ISO country code,
+ required: true,
+ schema: {
+ type: string
+ }
+ },
+ {
+ name: city,
+ in: query,
+ description: Name of city,
+ schema: {
+ type: string,
+ default: Seattle
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /zip-codes/validate: {
+ get: {
+ tags: [
+ FromQueryParams
+ ],
+ parameters: [
+ {
+ name: zipCodes,
+ in: query,
+ schema: {
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /Issue3013/Get: {
+ get: {
+ tags: [
+ Issue3013
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ text/plain: {
+ schema: {
+ $ref: #/components/schemas/TestResponse
+ }
+ },
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/TestResponse
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/TestResponse
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /promotions: {
+ get: {
+ tags: [
+ JsonAnnotations
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/Promotion
+ }
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /shapes: {
+ post: {
+ tags: [
+ PolymorphicTypes
+ ],
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ oneOf: [
+ null,
+ null
+ ]
+ }
+ },
+ text/json: {
+ schema: {
+ oneOf: [
+ null,
+ null
+ ]
+ }
+ },
+ application/*+json: {
+ schema: {
+ oneOf: [
+ null,
+ null
+ ]
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ text/plain: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ },
+ application/json: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ },
+ text/json: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /orders: {
+ post: {
+ tags: [
+ ResponseTypeAnnotations
+ ],
+ summary: Creates an order,
+ requestBody: {
+ description: ,
+ content: {
+ application/xml: {
+ schema: {
+ $ref: #/components/schemas/Order
+ }
+ }
+ },
+ required: true,
+ x-purpose: test
+ },
+ responses: {
+ 201: {
+ description: Order created,
+ content: {
+ application/xml: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ },
+ 400: {
+ description: Order invalid,
+ content: {
+ application/xml: {
+ schema: {
+ $ref: #/components/schemas/ValidationProblemDetails
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /carts: {
+ post: {
+ tags: [
+ SwaggerAnnotations
+ ],
+ operationId: CreateCart,
+ requestBody: {
+ description: The cart request body,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ }
+ },
+ x-purpose: test
+ },
+ responses: {
+ 201: {
+ description: The cart was created,
+ content: {
+ text/plain: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ }
+ }
+ },
+ 400: {
+ description: The cart data is invalid
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /carts/{id}: {
+ get: {
+ tags: [
+ SwaggerAnnotations
+ ],
+ externalDocs: {
+ description: External docs for CartsByIdGet,
+ url: https://tempuri.org/carts-by-id-get
+ },
+ operationId: GetCart,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: The cart identifier,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ text/plain: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ delete: {
+ tags: [
+ SwaggerAnnotations
+ ],
+ summary: Deletes a specific cart,
+ description: Requires admin privileges,
+ operationId: DeleteCart,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ description: The cart identifier,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ text/plain: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/Cart
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /stores: {
+ post: {
+ tags: [
+ UnboundParams
+ ],
+ parameters: [
+ {
+ name: id,
+ in: query,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ },
+ {
+ name: location,
+ in: query,
+ schema: {
+ type: string
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ get: {
+ tags: [
+ UnboundParams
+ ],
+ parameters: [
+ {
+ name: locations,
+ in: query,
+ schema: {
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/Store
+ }
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ }
+ },
+ /stores/{id}: {
+ get: {
+ tags: [
+ UnboundParams
+ ],
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/Store
+ }
+ }
+ }
+ }
+ },
+ x-purpose: test
+ },
+ put: {
+ tags: [
+ UnboundParams
+ ],
+ parameters: [
+ {
+ name: id,
+ in: query,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ },
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ },
+ {
+ name: location,
+ in: query,
+ schema: {
+ type: string
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ },
+ delete: {
+ tags: [
+ UnboundParams
+ ],
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: integer,
+ format: int32
+ }
+ }
+ ],
+ responses: {
+ 200: {
+ description: OK
+ }
+ },
+ x-purpose: test
+ }
+ }
+ },
+ components: {
+ schemas: {
+ Cart: {
+ required: [
+ Id
+ ],
+ type: object,
+ properties: {
+ id: {
+ type: integer,
+ description: The cart identifier,
+ format: int32,
+ readOnly: true
+ },
+ cartType: {
+ $ref: #/components/schemas/CartType
+ }
+ },
+ additionalProperties: false
+ },
+ CartType: {
+ enum: [
+ 0,
+ 1
+ ],
+ type: integer,
+ description: The cart type,
+ format: int32
+ },
+ Circle: {
+ allOf: [
+ null,
+ {
+ type: object,
+ properties: {
+ radius: {
+ type: integer,
+ format: int32
+ }
+ },
+ additionalProperties: false
+ }
+ ]
+ },
+ CreditCard: {
+ required: [
+ cardNumber,
+ expMonth,
+ expYear
+ ],
+ type: object,
+ properties: {
+ cardNumber: {
+ minLength: 1,
+ pattern: ^[3-6]?\d{12,15}$,
+ type: string
+ },
+ expMonth: {
+ maximum: 12,
+ minimum: 1,
+ type: integer,
+ format: int32
+ },
+ expYear: {
+ maximum: 99,
+ minimum: 14,
+ type: integer,
+ format: int32
+ }
+ },
+ additionalProperties: false
+ },
+ DiscountType: {
+ enum: [
+ Percentage,
+ Amount
+ ],
+ type: string
+ },
+ Order: {
+ type: object,
+ properties: {
+ id: {
+ type: integer,
+ format: int32
+ },
+ description: {
+ type: string,
+ nullable: true
+ },
+ total: {
+ type: number,
+ format: double
+ }
+ },
+ additionalProperties: false
+ },
+ PaymentRequest: {
+ required: [
+ creditCard,
+ transaction
+ ],
+ type: object,
+ properties: {
+ transaction: {
+ $ref: #/components/schemas/Transaction
+ },
+ creditCard: {
+ $ref: #/components/schemas/CreditCard
+ }
+ },
+ additionalProperties: false
+ },
+ Product: {
+ type: object,
+ properties: {
+ id: {
+ type: integer,
+ description: Uniquely identifies the product,
+ format: int32
+ },
+ description: {
+ type: string,
+ description: Describes the product,
+ nullable: true
+ },
+ status: {
+ $ref: #/components/schemas/ProductStatus
+ },
+ status2: {
+ $ref: #/components/schemas/ProductStatus
+ }
+ },
+ additionalProperties: false,
+ description: Represents a product,
+ example: {
+ id: 123,
+ description: foobar,
+ price: 14.37
+ }
+ },
+ ProductStatus: {
+ enum: [
+ 0,
+ 1,
+ 2
+ ],
+ type: integer,
+ format: int32
+ },
+ Promotion: {
+ type: object,
+ properties: {
+ promo-code: {
+ type: string,
+ nullable: true
+ },
+ discountType: {
+ $ref: #/components/schemas/DiscountType
+ }
+ },
+ additionalProperties: false
+ },
+ Rectangle: {
+ allOf: [
+ null,
+ {
+ type: object,
+ properties: {
+ height: {
+ type: integer,
+ format: int32
+ },
+ width: {
+ type: integer,
+ format: int32
+ }
+ },
+ additionalProperties: false
+ }
+ ]
+ },
+ Shape: {
+ required: [
+ TypeName
+ ],
+ type: object,
+ properties: {
+ TypeName: {
+ type: string
+ },
+ name: {
+ type: string,
+ nullable: true
+ }
+ },
+ additionalProperties: false,
+ discriminator: {
+ propertyName: TypeName,
+ mapping: {
+ Rectangle: #/components/schemas/Rectangle,
+ Circle: #/components/schemas/Circle
+ }
+ }
+ },
+ Store: {
+ type: object,
+ properties: {
+ id: {
+ type: integer,
+ format: int32
+ },
+ location: {
+ type: string,
+ nullable: true
+ }
+ },
+ additionalProperties: false
+ },
+ TestResponse: {
+ type: object,
+ properties: {
+ foo: {
+ $ref: #/components/schemas/TestStruct
+ }
+ },
+ additionalProperties: false
+ },
+ TestStruct: {
+ type: object,
+ properties: {
+ a: {
+ type: integer,
+ format: int32
+ },
+ b: {
+ type: integer,
+ format: int32
+ }
+ },
+ additionalProperties: false
+ },
+ Transaction: {
+ required: [
+ amount
+ ],
+ type: object,
+ properties: {
+ amount: {
+ type: number,
+ format: double
+ },
+ note: {
+ type: string,
+ nullable: true
+ }
+ },
+ additionalProperties: false
+ },
+ ValidationProblemDetails: {
+ type: object,
+ properties: {
+ type: {
+ type: string,
+ nullable: true
+ },
+ title: {
+ type: string,
+ nullable: true
+ },
+ status: {
+ type: integer,
+ format: int32,
+ nullable: true
+ },
+ detail: {
+ type: string,
+ nullable: true
+ },
+ instance: {
+ type: string,
+ nullable: true
+ },
+ errors: {
+ type: object,
+ additionalProperties: {
+ type: array,
+ items: {
+ type: string
+ }
+ },
+ nullable: true
+ }
+ }
+ }
+ }
+ },
+ tags: [
+ {
+ name: SwaggerAnnotations,
+ description: Manipulate Carts to your heart's content,
+ externalDocs: {
+ url: http://www.tempuri.org
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_startupType=Basic.Startup_swaggerRequestUri=v1.verified.txt b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_startupType=Basic.Startup_swaggerRequestUri=v1.verified.txt
deleted file mode 100644
index 4d9e556dc5..0000000000
--- a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_startupType=Basic.Startup_swaggerRequestUri=v1.verified.txt
+++ /dev/null
@@ -1,1497 +0,0 @@
-{
- "openapi": "3.0.1",
- "info": {
- "title": "Test API V1",
- "description": "A sample API for testing Swashbuckle",
- "termsOfService": "http://tempuri.org/terms",
- "version": "v1"
- },
- "paths": {
- "/products": {
- "post": {
- "tags": [
- "CrudActions"
- ],
- "summary": "Creates a product",
- "description": "## Heading 1\r\n\r\n POST /products\r\n {\r\n \"id\": \"123\",\r\n \"description\": \"Some product\"\r\n }",
- "operationId": "CreateProduct",
- "requestBody": {
- "description": "",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Product"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Product"
- }
- },
- "application/*+json": {
- "schema": {
- "$ref": "#/components/schemas/Product"
- }
- }
- },
- "required": true,
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Product"
- }
- }
- }
- }
- },
- "x-purpose": "test"
- },
- "get": {
- "tags": [
- "CrudActions"
- ],
- "summary": "Searches the collection of products by description key words",
- "operationId": "SearchProducts",
- "parameters": [
- {
- "name": "kw",
- "in": "query",
- "description": "A list of search terms",
- "schema": {
- "type": "string",
- "default": "foobar"
- },
- "example": "hello"
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Product"
- }
- }
- }
- }
- }
- },
- "x-purpose": "test"
- }
- },
- "/products/{id}": {
- "get": {
- "tags": [
- "CrudActions"
- ],
- "summary": "Returns a specific product",
- "operationId": "GetProduct",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "description": "The product id",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int32"
- },
- "example": 111
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Product"
- }
- }
- }
- }
- },
- "x-purpose": "test"
- },
- "put": {
- "tags": [
- "CrudActions"
- ],
- "summary": "Updates all properties of a specific product",
- "operationId": "UpdateProduct",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "description": "",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int32"
- },
- "example": 222
- }
- ],
- "requestBody": {
- "description": "",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Product"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Product"
- }
- },
- "application/*+json": {
- "schema": {
- "$ref": "#/components/schemas/Product"
- }
- }
- },
- "required": true,
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- },
- "patch": {
- "tags": [
- "CrudActions"
- ],
- "summary": "Updates some properties of a specific product",
- "operationId": "PatchProduct",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "description": "",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int32"
- },
- "example": 333
- }
- ],
- "requestBody": {
- "description": "",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "additionalProperties": { }
- }
- },
- "text/json": {
- "schema": {
- "type": "object",
- "additionalProperties": { }
- }
- },
- "application/*+json": {
- "schema": {
- "type": "object",
- "additionalProperties": { }
- }
- }
- },
- "required": true,
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- },
- "delete": {
- "tags": [
- "CrudActions"
- ],
- "summary": "Deletes a specific product",
- "operationId": "DeleteProduct",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "description": "",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int32"
- },
- "example": 444
- }
- ],
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/payments/authorize": {
- "post": {
- "tags": [
- "DataAnnotations"
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/PaymentRequest"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/PaymentRequest"
- }
- },
- "application/*+json": {
- "schema": {
- "$ref": "#/components/schemas/PaymentRequest"
- }
- }
- },
- "required": true,
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "type": "string"
- }
- }
- }
- }
- },
- "x-purpose": "test"
- }
- },
- "/payments/{paymentId}/cancel": {
- "put": {
- "tags": [
- "DataAnnotations"
- ],
- "parameters": [
- {
- "name": "paymentId",
- "in": "path",
- "required": true,
- "schema": {
- "minLength": 6,
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/kittens": {
- "post": {
- "tags": [
- "DynamicTypes"
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": { }
- },
- "text/json": {
- "schema": { }
- },
- "application/*+json": {
- "schema": { }
- }
- },
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- }
- }
- },
- "x-purpose": "test"
- }
- },
- "/unicorns": {
- "get": {
- "tags": [
- "DynamicTypes"
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "additionalProperties": { }
- }
- }
- }
- }
- },
- "x-purpose": "test"
- }
- },
- "/dragons": {
- "post": {
- "tags": [
- "DynamicTypes"
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": { }
- },
- "text/json": {
- "schema": { }
- },
- "application/*+json": {
- "schema": { }
- }
- },
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/files/single": {
- "post": {
- "tags": [
- "Files"
- ],
- "requestBody": {
- "content": {
- "multipart/form-data": {
- "schema": {
- "type": "object",
- "properties": {
- "file": {
- "type": "string",
- "format": "binary"
- }
- }
- },
- "encoding": {
- "file": {
- "style": "form"
- }
- }
- }
- },
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/files/multiple": {
- "post": {
- "tags": [
- "Files"
- ],
- "requestBody": {
- "content": {
- "multipart/form-data": {
- "schema": {
- "type": "object",
- "properties": {
- "files": {
- "type": "array",
- "items": {
- "type": "string",
- "format": "binary"
- }
- }
- }
- },
- "encoding": {
- "files": {
- "style": "form"
- }
- }
- }
- },
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/files/form-with-file": {
- "post": {
- "tags": [
- "Files"
- ],
- "requestBody": {
- "content": {
- "multipart/form-data": {
- "schema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "file": {
- "type": "string",
- "format": "binary"
- }
- }
- },
- "encoding": {
- "name": {
- "style": "form"
- },
- "file": {
- "style": "form"
- }
- }
- }
- },
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/files/{name}": {
- "get": {
- "tags": [
- "Files"
- ],
- "parameters": [
- {
- "name": "name",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "text/plain": {
- "schema": {
- "oneOf": [
- {
- "type": "string",
- "format": "binary"
- },
- {
- "type": "string",
- "format": "binary"
- },
- {
- "type": "string",
- "format": "binary"
- },
- {
- "type": "string",
- "format": "binary"
- }
- ]
- }
- },
- "application/zip": {
- "schema": {
- "oneOf": [
- {
- "type": "string",
- "format": "binary"
- },
- {
- "type": "string",
- "format": "binary"
- },
- {
- "type": "string",
- "format": "binary"
- },
- {
- "type": "string",
- "format": "binary"
- }
- ]
- }
- }
- }
- }
- },
- "x-purpose": "test"
- }
- },
- "/registrations": {
- "post": {
- "tags": [
- "FromFormParams"
- ],
- "requestBody": {
- "content": {
- "application/x-www-form-urlencoded": {
- "schema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "phoneNumbers": {
- "type": "array",
- "items": {
- "type": "integer",
- "format": "int32"
- }
- }
- }
- },
- "encoding": {
- "name": {
- "style": "form"
- },
- "phoneNumbers": {
- "style": "form"
- }
- }
- }
- },
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/registrationsWithIgnoreProperties": {
- "post": {
- "tags": [
- "FromFormParams"
- ],
- "requestBody": {
- "content": {
- "multipart/form-data": {
- "schema": {
- "required": [
- "country"
- ],
- "type": "object",
- "properties": {
- "phoneNumbers": {
- "type": "array",
- "items": {
- "type": "integer",
- "format": "int32"
- }
- },
- "country": {
- "type": "string",
- "description": "3-letter ISO country code"
- },
- "city": {
- "type": "string",
- "description": "Name of city",
- "default": "Seattle"
- }
- }
- },
- "encoding": {
- "phoneNumbers": {
- "style": "form"
- },
- "country": {
- "style": "form"
- },
- "city": {
- "style": "form"
- }
- }
- }
- },
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/country/validate": {
- "get": {
- "tags": [
- "FromHeaderParams"
- ],
- "parameters": [
- {
- "name": "country",
- "in": "query",
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/addresses/validate": {
- "get": {
- "tags": [
- "FromQueryParams"
- ],
- "parameters": [
- {
- "name": "country",
- "in": "query",
- "description": "3-letter ISO country code",
- "required": true,
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "city",
- "in": "query",
- "description": "Name of city",
- "schema": {
- "type": "string",
- "default": "Seattle"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/zip-codes/validate": {
- "get": {
- "tags": [
- "FromQueryParams"
- ],
- "parameters": [
- {
- "name": "zipCodes",
- "in": "query",
- "schema": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- },
- "/promotions": {
- "get": {
- "tags": [
- "JsonAnnotations"
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Promotion"
- }
- }
- }
- }
- }
- },
- "x-purpose": "test"
- }
- },
- "/shapes": {
- "post": {
- "tags": [
- "PolymorphicTypes"
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "oneOf": [
- {
- "$ref": "#/components/schemas/Rectangle"
- },
- {
- "$ref": "#/components/schemas/Circle"
- }
- ]
- }
- },
- "text/json": {
- "schema": {
- "oneOf": [
- {
- "$ref": "#/components/schemas/Rectangle"
- },
- {
- "$ref": "#/components/schemas/Circle"
- }
- ]
- }
- },
- "application/*+json": {
- "schema": {
- "oneOf": [
- {
- "$ref": "#/components/schemas/Rectangle"
- },
- {
- "$ref": "#/components/schemas/Circle"
- }
- ]
- }
- }
- },
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "text/plain": {
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- },
- "application/json": {
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- },
- "text/json": {
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- }
- }
- },
- "x-purpose": "test"
- }
- },
- "/orders": {
- "post": {
- "tags": [
- "ResponseTypeAnnotations"
- ],
- "summary": "Creates an order",
- "requestBody": {
- "description": "",
- "content": {
- "application/xml": {
- "schema": {
- "$ref": "#/components/schemas/Order"
- }
- }
- },
- "required": true,
- "x-purpose": "test"
- },
- "responses": {
- "201": {
- "description": "Order created",
- "content": {
- "application/xml": {
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- }
- },
- "400": {
- "description": "Order invalid",
- "content": {
- "application/xml": {
- "schema": {
- "$ref": "#/components/schemas/ValidationProblemDetails"
- }
- }
- }
- }
- },
- "x-purpose": "test"
- }
- },
- "/carts": {
- "post": {
- "tags": [
- "SwaggerAnnotations"
- ],
- "operationId": "CreateCart",
- "requestBody": {
- "description": "The cart request body",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- },
- "application/*+json": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- }
- },
- "x-purpose": "test"
- },
- "responses": {
- "201": {
- "description": "The cart was created",
- "content": {
- "text/plain": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- },
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- }
- }
- },
- "400": {
- "description": "The cart data is invalid"
- }
- },
- "x-purpose": "test"
- }
- },
- "/carts/{id}": {
- "get": {
- "tags": [
- "SwaggerAnnotations"
- ],
- "externalDocs": {
- "description": "External docs for CartsByIdGet",
- "url": "https://tempuri.org/carts-by-id-get"
- },
- "operationId": "GetCart",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "description": "The cart identifier",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "text/plain": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- },
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- }
- }
- }
- },
- "x-purpose": "test"
- },
- "delete": {
- "tags": [
- "SwaggerAnnotations"
- ],
- "summary": "Deletes a specific cart",
- "description": "Requires admin privileges",
- "operationId": "DeleteCart",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "description": "The cart identifier",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "text/plain": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- },
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Cart"
- }
- }
- }
- }
- },
- "x-purpose": "test"
- }
- },
- "/stores": {
- "post": {
- "tags": [
- "UnboundParams"
- ],
- "parameters": [
- {
- "name": "id",
- "in": "query",
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- },
- {
- "name": "location",
- "in": "query",
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- }
- }
- },
- "x-purpose": "test"
- },
- "get": {
- "tags": [
- "UnboundParams"
- ],
- "parameters": [
- {
- "name": "locations",
- "in": "query",
- "schema": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Store"
- }
- }
- }
- }
- }
- },
- "x-purpose": "test"
- }
- },
- "/stores/{id}": {
- "get": {
- "tags": [
- "UnboundParams"
- ],
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Store"
- }
- }
- }
- }
- },
- "x-purpose": "test"
- },
- "put": {
- "tags": [
- "UnboundParams"
- ],
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Store"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Store"
- }
- },
- "application/*+json": {
- "schema": {
- "$ref": "#/components/schemas/Store"
- }
- }
- },
- "x-purpose": "test"
- },
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- },
- "delete": {
- "tags": [
- "UnboundParams"
- ],
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK"
- }
- },
- "x-purpose": "test"
- }
- }
- },
- "components": {
- "schemas": {
- "Cart": {
- "required": [
- "Id"
- ],
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "description": "The cart identifier",
- "format": "int32",
- "readOnly": true
- },
- "cartType": {
- "$ref": "#/components/schemas/CartType"
- }
- },
- "additionalProperties": false
- },
- "CartType": {
- "enum": [
- 0,
- 1
- ],
- "type": "integer",
- "description": "The cart type",
- "format": "int32"
- },
- "Circle": {
- "allOf": [
- {
- "$ref": "#/components/schemas/Shape"
- },
- {
- "type": "object",
- "properties": {
- "radius": {
- "type": "integer",
- "format": "int32"
- }
- },
- "additionalProperties": false
- }
- ]
- },
- "CreditCard": {
- "required": [
- "cardNumber",
- "expMonth",
- "expYear"
- ],
- "type": "object",
- "properties": {
- "cardNumber": {
- "minLength": 1,
- "pattern": "^[3-6]?\\d{12,15}$",
- "type": "string"
- },
- "expMonth": {
- "maximum": 12,
- "minimum": 1,
- "type": "integer",
- "format": "int32"
- },
- "expYear": {
- "maximum": 99,
- "minimum": 14,
- "type": "integer",
- "format": "int32"
- }
- },
- "additionalProperties": false
- },
- "DiscountType": {
- "enum": [
- "Percentage",
- "Amount"
- ],
- "type": "string"
- },
- "Order": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "format": "int32"
- },
- "description": {
- "type": "string",
- "nullable": true
- },
- "total": {
- "type": "number",
- "format": "double"
- }
- },
- "additionalProperties": false
- },
- "PaymentRequest": {
- "required": [
- "creditCard",
- "transaction"
- ],
- "type": "object",
- "properties": {
- "transaction": {
- "$ref": "#/components/schemas/Transaction"
- },
- "creditCard": {
- "$ref": "#/components/schemas/CreditCard"
- }
- },
- "additionalProperties": false
- },
- "Product": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "description": "Uniquely identifies the product",
- "format": "int32"
- },
- "description": {
- "type": "string",
- "description": "Describes the product",
- "nullable": true
- },
- "status": {
- "$ref": "#/components/schemas/ProductStatus"
- },
- "status2": {
- "$ref": "#/components/schemas/ProductStatus"
- }
- },
- "additionalProperties": false,
- "description": "Represents a product",
- "example": {
- "id": 123,
- "description": "foobar",
- "price": 14.37
- }
- },
- "ProductStatus": {
- "enum": [
- 0,
- 1,
- 2
- ],
- "type": "integer",
- "format": "int32"
- },
- "Promotion": {
- "type": "object",
- "properties": {
- "promo-code": {
- "type": "string",
- "nullable": true
- },
- "discountType": {
- "$ref": "#/components/schemas/DiscountType"
- }
- },
- "additionalProperties": false
- },
- "Rectangle": {
- "allOf": [
- {
- "$ref": "#/components/schemas/Shape"
- },
- {
- "type": "object",
- "properties": {
- "height": {
- "type": "integer",
- "format": "int32"
- },
- "width": {
- "type": "integer",
- "format": "int32"
- }
- },
- "additionalProperties": false
- }
- ]
- },
- "Shape": {
- "required": [
- "TypeName"
- ],
- "type": "object",
- "properties": {
- "TypeName": {
- "type": "string"
- },
- "name": {
- "type": "string",
- "nullable": true
- }
- },
- "additionalProperties": false,
- "discriminator": {
- "propertyName": "TypeName",
- "mapping": {
- "Rectangle": "#/components/schemas/Rectangle",
- "Circle": "#/components/schemas/Circle"
- }
- }
- },
- "Store": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "format": "int32"
- },
- "location": {
- "type": "string",
- "nullable": true
- }
- },
- "additionalProperties": false
- },
- "Transaction": {
- "required": [
- "amount"
- ],
- "type": "object",
- "properties": {
- "amount": {
- "type": "number",
- "format": "double"
- },
- "note": {
- "type": "string",
- "nullable": true
- }
- },
- "additionalProperties": false
- },
- "ValidationProblemDetails": {
- "type": "object",
- "properties": {
- "type": {
- "type": "string",
- "nullable": true
- },
- "title": {
- "type": "string",
- "nullable": true
- },
- "status": {
- "type": "integer",
- "format": "int32",
- "nullable": true
- },
- "detail": {
- "type": "string",
- "nullable": true
- },
- "instance": {
- "type": "string",
- "nullable": true
- },
- "errors": {
- "type": "object",
- "additionalProperties": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "nullable": true
- }
- },
- "additionalProperties": { }
- }
- }
- },
- "tags": [
- {
- "name": "SwaggerAnnotations",
- "description": "Manipulate Carts to your heart's content",
- "externalDocs": {
- "url": "http://www.tempuri.org"
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs
index 142969bff3..ca92a7e86c 100644
--- a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs
+++ b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs
@@ -9,7 +9,7 @@
namespace Swashbuckle.AspNetCore.IntegrationTests
{
[Collection("TestSite")]
- public class SwaggerVerifyIntegrationTest
+ public partial class SwaggerVerifyIntegrationTest
{
[Theory]
[InlineData(typeof(CliExample.Startup), "/swagger/v1/swagger_net8.0.json")]
@@ -34,7 +34,31 @@ public async Task SwaggerEndpoint_ReturnsValidSwaggerJson(
await Verifier.Verify(swagger).UseParameters(startupType, GetVersion(swaggerRequestUri));
}
+#if NET6_0
+ [Fact]
+ public async Task SwaggerEndpoint_ReturnsValidSwaggerJson_Basic_DotNet_6()
+ {
+ var testSite = new TestSite(typeof(Basic.Startup));
+ using var client = testSite.BuildClient();
+
+ using var swaggerResponse = await client.GetAsync("/swagger/v1/swagger.json");
+ var swagger = await swaggerResponse.Content.ReadAsStringAsync();
+ await Verifier.VerifyJson(swagger);
+ }
+#endif
+
#if NET8_0_OR_GREATER
+ [Fact]
+ public async Task SwaggerEndpoint_ReturnsValidSwaggerJson_Basic_DotNet_8()
+ {
+ var testSite = new TestSite(typeof(Basic.Startup));
+ using var client = testSite.BuildClient();
+
+ using var swaggerResponse = await client.GetAsync("/swagger/v1/swagger.json");
+ var swagger = await swaggerResponse.Content.ReadAsStringAsync();
+ await Verifier.VerifyJson(swagger);
+ }
+
[Theory]
[InlineData("/swagger/v1/swagger.json")]
public async Task SwaggerEndpoint_ReturnsValidSwaggerJson_For_WebApi(
@@ -71,13 +95,21 @@ private static async Task SwaggerEndpointReturnsValidSwaggerJson SwaggerResponse(HttpClient client, string swaggerRequestUri)
{
using var swaggerResponse = await client.GetAsync(swaggerRequestUri);
var contentStream = await swaggerResponse.Content.ReadAsStringAsync();
return contentStream;
}
- private static string GetVersion(string swaggerUi) => Regex.Match(swaggerUi, "/\\w+/([\\w+\\d+.-]+)/").Groups[1].Value;
+#endif
+ private static string GetVersion(string swaggerUi) =>
+#if NET6_0
+ Regex.Match(swaggerUi, "/\\w+/([\\w+\\d+.-]+)/").Groups[1].Value;
+#else
+ VersionRegex().Match(swaggerUi).Groups[1].Value;
+
+ [GeneratedRegex("/\\w+/([\\w+\\d+.-]+)/")]
+ private static partial Regex VersionRegex();
+#endif
}
}
diff --git a/test/WebSites/Basic/Controllers/Issue3013Controller.cs b/test/WebSites/Basic/Controllers/Issue3013Controller.cs
new file mode 100644
index 0000000000..ab6cbe7aab
--- /dev/null
+++ b/test/WebSites/Basic/Controllers/Issue3013Controller.cs
@@ -0,0 +1,26 @@
+#if NET6_0_OR_GREATER
+using Microsoft.AspNetCore.Mvc;
+
+namespace Basic.Controllers;
+
+[ApiController]
+[Route("[controller]/[action]")]
+public class Issue3013Controller : ControllerBase
+{
+ [HttpGet]
+ public TestResponse Get()
+ {
+ return new()
+ {
+ Foo = new(1, 2),
+ };
+ }
+
+ public record TestResponse
+ {
+ public TestStruct? Foo { get; init; }
+ }
+
+ public record struct TestStruct(int A, int B);
+}
+#endif
diff --git a/test/WebSites/NswagClientExample/NswagClientExample.csproj b/test/WebSites/NswagClientExample/NswagClientExample.csproj
index 4ee15c17f8..6b3282425d 100644
--- a/test/WebSites/NswagClientExample/NswagClientExample.csproj
+++ b/test/WebSites/NswagClientExample/NswagClientExample.csproj
@@ -9,7 +9,7 @@
-
+