Description
Description
when multiple content types are generated or when anyways oneOf
/ allOf
is used in response type, swagger provider results in 'obj' response type, or request type also (e.g. with json , text, and other formts, does not filter only application/json but breaks and returns object)
Repro steps
Please provide the steps required to reproduce the problem
- Type provider type definition with parameters
type ChangeApi = OpenApiClientProvider<"test.yaml">
- Sample schema or relevant schema part
openapi: 3.0.1
info:
title: Acme.TestServiceBlaBla.WebService
version: v1
paths:
'/orders/{orderNumber}/change-eligibility':
get:
tags:
- EligibilityChange
summary: Gets eligibilities of products for the order by a orderNumber.
parameters:
- name: orderNumber
in: path
description: The order number.
required: true
schema:
type: string
- name: enableCacmeSelfService
in: query
description: ''
schema:
type: boolean
default: false
responses:
'200':
description: Success
content:
text/plain:
schema:
$ref: '#/components/schemas/EligibilityResponse'
application/json:
schema:
$ref: '#/components/schemas/EligibilityResponse'
text/json:
schema:
$ref: '#/components/schemas/EligibilityResponse'
'404':
description: Not Found
content:
text/plain:
schema:
$ref: '#/components/schemas/EligibilityErrorResponse'
application/json:
schema:
$ref: '#/components/schemas/EligibilityErrorResponse'
text/json:
schema:
$ref: '#/components/schemas/EligibilityErrorResponse'
'500':
description: Server Error
content:
text/plain:
schema:
$ref: '#/components/schemas/EligibilityErrorResponse'
application/json:
schema:
$ref: '#/components/schemas/EligibilityErrorResponse'
text/json:
schema:
$ref: '#/components/schemas/EligibilityErrorResponse'
'409':
description: Conflict
content:
text/plain:
schema:
$ref: '#/components/schemas/EligibilityErrorResponse'
application/json:
schema:
$ref: '#/components/schemas/EligibilityErrorResponse'
text/json:
schema:
$ref: '#/components/schemas/EligibilityErrorResponse'
'/flights/exchange':
post:
tags:
- FlightExchange
requestBody:
content:
application/json-patch+json:
schema:
allOf:
- $ref: '#/components/schemas/FlightExchangeRequest'
application/json:
schema:
allOf:
- $ref: '#/components/schemas/FlightExchangeRequest'
text/json:
schema:
allOf:
- $ref: '#/components/schemas/FlightExchangeRequest'
application/*+json:
schema:
allOf:
- $ref: '#/components/schemas/FlightExchangeRequest'
responses:
'200':
description: Success
content:
text/plain:
schema:
$ref: '#/components/schemas/FlightExchangeResponse'
application/json:
schema:
$ref: '#/components/schemas/FlightExchangeResponse'
text/json:
schema:
$ref: '#/components/schemas/FlightExchangeResponse'
'500':
description: Server Error
content:
text/plain:
schema:
$ref: '#/components/schemas/ReshopErrorResponse'
application/json:
schema:
$ref: '#/components/schemas/ReshopErrorResponse'
text/json:
schema:
$ref: '#/components/schemas/ReshopErrorResponse'
'/flights/exchange/{exchangeRequestId}':
get:
tags:
- FlightExchange
parameters:
- name: exchangeRequestId
in: path
required: true
description: for Cacme this will be the key identifier of an offer
schema:
type: string
responses:
'200':
description: Success
content:
text/plain:
schema:
$ref: '#/components/schemas/FlightExchangeDetailResponse'
application/json:
schema:
$ref: '#/components/schemas/FlightExchangeDetailResponse'
text/json:
schema:
$ref: '#/components/schemas/FlightExchangeDetailResponse'
'404':
description: Not Found
'500':
description: Server Error
'/flights/exchange/{exchangeRequestId}/status':
get:
tags:
- FlightExchange
parameters:
- name: exchangeRequestId
in: path
required: true
description: for Cacme this will be the key identifier of an offer
schema:
type: string
responses:
'200':
description: Success
content:
text/plain:
schema:
$ref: '#/components/schemas/FlightExchangeStatusResponse'
application/json:
schema:
$ref: '#/components/schemas/FlightExchangeStatusResponse'
text/json:
schema:
$ref: '#/components/schemas/FlightExchangeStatusResponse'
'404':
description: Not Found
'500':
description: Server Error
'/flights/exchange/{exchangeRequestId}/submit':
post:
tags:
- FlightExchange
parameters:
- name: exchangeRequestId
in: path
required: true
description: for Cacme this will be the key identifier of an offer
schema:
type: string
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/FlightSubmitExchangeResponse'
'/orders/{orderNumber}/flights/{productId}/reshop':
post:
tags:
- Reshop
parameters:
- name: orderNumber
in: path
required: true
schema:
type: string
- name: productId
in: path
required: true
schema:
type: string
requestBody:
content:
application/json-patch+json:
schema:
allOf:
- $ref: '#/components/schemas/ReshopRequest'
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ReshopRequest'
text/json:
schema:
allOf:
- $ref: '#/components/schemas/ReshopRequest'
application/*+json:
schema:
allOf:
- $ref: '#/components/schemas/ReshopRequest'
responses:
'200':
description: Success
content:
text/plain:
schema:
$ref: '#/components/schemas/ReshopResponse'
application/json:
schema:
$ref: '#/components/schemas/ReshopResponse'
text/json:
schema:
$ref: '#/components/schemas/ReshopResponse'
'204':
description: No Content
'500':
description: Server Error
content:
text/plain:
schema:
$ref: '#/components/schemas/ReshopErrorResponse'
application/json:
schema:
$ref: '#/components/schemas/ReshopErrorResponse'
text/json:
schema:
$ref: '#/components/schemas/ReshopErrorResponse'
components:
schemas:
FlightSubmitExchangeResponse:
type: object
properties:
paymentIdentifier:
type: string
nullable: false
FlightExchangeStatusResponse:
type: object
properties:
status:
type: string
description: confirmed | timeout | error
nullable: false
AmountWithCurrency:
type: object
properties:
value:
type: number
format: double
currencyCode:
type: string
nullable: true
additionalProperties: false
Baggage:
type: object
properties:
quantity:
type: integer
format: int32
nullable: true
unit:
type: string
nullable: true
value:
type: integer
format: int32
nullable: true
additionalProperties: false
CancellationDetails:
type: object
properties:
automatedCancellation:
type: boolean
cancellable:
type: boolean
reason:
type: string
nullable: true
feeDetails:
allOf:
- $ref: '#/components/schemas/FeeDetails'
nullable: true
refundDetails:
allOf:
- $ref: '#/components/schemas/RefundDetails'
nullable: true
nonRefundableDetails:
allOf:
- $ref: '#/components/schemas/NonRefundableDetails'
nullable: true
totalPaid:
allOf:
- $ref: '#/components/schemas/AmountWithCurrency'
nullable: true
revisedTotal:
allOf:
- $ref: '#/components/schemas/AmountWithCurrency'
nullable: true
totalRefund:
allOf:
- $ref: '#/components/schemas/AmountWithCurrency'
nullable: true
additionalProperties: false
ChangeDetail:
required:
- exchangeType
- value
type: object
properties:
exchangeType:
minLength: 1
type: string
value:
minLength: 1
type: string
additionalProperties: false
ChangeDetails:
type: object
properties:
automatedChange:
type: boolean
changeable:
type: boolean
reason:
type: string
nullable: true
validity:
allOf:
- $ref: '#/components/schemas/ChangeValidity'
nullable: true
additionalProperties: false
ChangeValidity:
type: object
properties:
dates:
allOf:
- $ref: '#/components/schemas/ChangeValidityDates'
nullable: true
additionalProperties: false
ChangeValidityDates:
type: object
properties:
legs:
type: array
items:
$ref: '#/components/schemas/ChangeValidityDatesLeg'
nullable: true
additionalProperties: false
ChangeValidityDatesLeg:
type: object
properties:
id:
type: integer
format: int32
minDepartureDate:
type: string
nullable: true
maxDepartureDate:
type: string
nullable: true
additionalProperties: false
Commission:
type: object
properties:
amount:
type: number
format: double
type:
type: string
nullable: true
additionalProperties: false
EligibilityErrorResponse:
type: object
properties:
details:
nullable: true
errorCode:
type: string
nullable: true
errorInfo:
type: string
nullable: true
additionalProperties: false
EligibilityItemResponse:
type: object
properties:
id:
type: string
format: uuid
flowType:
allOf:
- $ref: '#/components/schemas/FlowType'
voidWindowExpiry:
type: string
format: date-time
nullable: true
cancellationDetails:
allOf:
- $ref: '#/components/schemas/CancellationDetails'
nullable: true
changeDetails:
allOf:
- $ref: '#/components/schemas/ChangeDetails'
nullable: true
isWithinVoidWindow:
type: boolean
additionalProperties: false
EligibilityResponse:
type: object
properties:
eligibilityList:
type: array
items:
$ref: '#/components/schemas/EligibilityItemResponse'
nullable: true
additionalProperties: false
ExchangeItineraryFare:
type: object
properties:
fareId:
type: string
nullable: true
changeFees:
allOf:
- $ref: '#/components/schemas/AmountWithCurrency'
nullable: true
fareGroup:
allOf:
- $ref: '#/components/schemas/FareGroup'
nullable: true
legs:
type: array
items:
$ref: '#/components/schemas/Leg'
nullable: true
isFreeChange:
type: boolean
additionalProperties: false
ExchangeLeg:
required:
- changeDetails
- legId
type: object
properties:
legId:
type: integer
format: int32
changeDetails:
type: array
items:
$ref: '#/components/schemas/ChangeDetail'
additionalProperties: false
FareGroup:
type: object
properties:
brandName:
type: string
nullable: true
currency:
type: string
nullable: true
fareType:
type: string
nullable: true
id:
type: integer
format: int32
nullable: true
marketingCarrier:
type: string
nullable: true
passengerGroups:
type: array
items:
$ref: '#/components/schemas/PassengerGroup'
nullable: true
passiveSegmentIds:
type: array
items:
type: integer
format: int32
nullable: true
pointOfSale:
type: string
nullable: true
provider:
type: string
nullable: true
providerAccount:
type: string
nullable: true
segmentIds:
type: array
items:
type: integer
format: int32
nullable: true
validatingCarrier:
type: string
nullable: true
additionalProperties: false
FareInfo:
type: object
properties:
baggage:
allOf:
- $ref: '#/components/schemas/Baggage'
nullable: true
readOnly: true
baggageAllowance:
type: string
nullable: true
readOnly: true
segmentId:
type: integer
format: int32
nullable: true
readOnly: true
additionalProperties: false
FarePrice:
type: object
properties:
baseFare:
type: number
format: double
tax:
type: number
format: double
taxElements:
type: array
items:
$ref: '#/components/schemas/TaxElement'
nullable: true
readOnly: true
additionalProperties: false
Fee:
type: object
properties:
amount:
allOf:
- $ref: '#/components/schemas/AmountWithCurrency'
nullable: true
type:
type: string
nullable: true
name:
type: string
nullable: true
additionalProperties: false
FeeDetails:
type: object
properties:
fees:
type: array
items:
$ref: '#/components/schemas/Fee'
nullable: true
feesTotal:
allOf:
- $ref: '#/components/schemas/AmountWithCurrency'
nullable: true
additionalProperties: false
FlightExchangeDetailResponse:
type: object
properties:
productId:
type: string
format: uuid
quoteId:
type: string
nullable: true
orderNumber:
type: string
nullable: true
feeDetails:
allOf:
- $ref: '#/components/schemas/FeeDetails'
nullable: true
filteredFare:
allOf:
- $ref: '#/components/schemas/ExchangeItineraryFare'
nullable: true
additionalProperties: false
FlightExchangeRequest:
type: object
properties:
quoteId:
type: string
nullable: true
fareId:
type: string
nullable: true
productId:
type: string
format: uuid
orderNumber:
type: string
nullable: true
legs:
type: array
items:
type: integer
format: int32
nullable: true
additionalProperties: false
FlightExchangeResponse:
type: object
properties:
exchangeRequestId:
type: string
nullable: true
description: for Cacme this is the key identifier of an Offer
productId:
type: string
format: uuid
orderNumber:
type: string
nullable: true
feeDetails:
allOf:
- $ref: '#/components/schemas/FeeDetails'
nullable: true
orderSource:
type: string
nullable: true
additionalProperties: false
FlowType:
enum:
- SingleFlight
- CowFlight
- EtdPackage
type: string
Leg:
type: object
properties:
id:
type: integer
format: int32
legRef:
type: integer
format: int32
arrivalCode:
type: string
nullable: true
arrivalCountry:
type: string
nullable: true
arrivalDateTime:
type: string
format: date-time
arrivalRegion:
type: string
nullable: true
departureCode:
type: string
nullable: true
departureCountry:
type: string
nullable: true
departureDateTime:
type: string
format: date-time
departureRegion:
type: string
nullable: true
distanceKms:
type: integer
format: int32
nullable: true
durationMins:
type: integer
format: int32
nullable: true
marketingCarrier:
type: string
nullable: true
segments:
type: array
items:
$ref: '#/components/schemas/Segment'
nullable: true
cabinClassCompatibility:
type: boolean
additionalProperties: false
NonRefundableDetails:
type: object
properties:
fees:
type: array
items:
$ref: '#/components/schemas/NonRefundableFee'
nullable: true
nonRefundableFeesTotal:
allOf:
- $ref: '#/components/schemas/AmountWithCurrency'
nullable: true
additionalProperties: false
NonRefundableFee:
type: object
properties:
amount:
allOf:
- $ref: '#/components/schemas/AmountWithCurrency'
nullable: true
type:
type: string
nullable: true
name:
type: string
nullable: true
additionalProperties: false
PassengerFare:
type: object
properties:
newFarePrice:
allOf:
- $ref: '#/components/schemas/FarePrice'
nullable: true
fareDifference:
allOf:
- $ref: '#/components/schemas/FarePrice'
nullable: true
id:
type: integer
format: int32
numberOfPassengers:
type: integer
format: int32
passengerType:
type: string
nullable: true
passengerTypeCode:
type: string
nullable: true
additionalProperties: false
PassengerGroup:
type: object
properties:
commission:
allOf:
- $ref: '#/components/schemas/Commission'
nullable: true
fareInfos:
type: array
items:
$ref: '#/components/schemas/FareInfo'
nullable: true
passengerFare:
allOf:
- $ref: '#/components/schemas/PassengerFare'
nullable: true
passengerIds:
type: array
items:
type: integer
format: int32
nullable: true
additionalProperties: false
Refund:
type: object
properties:
amount:
allOf:
- $ref: '#/components/schemas/AmountWithCurrency'
nullable: true
type:
type: string
nullable: true
name:
type: string
nullable: true
additionalProperties: false
RefundDetails:
type: object
properties:
refunds:
type: array
items:
$ref: '#/components/schemas/Refund'
nullable: true
refundsTotal:
allOf:
- $ref: '#/components/schemas/AmountWithCurrency'
nullable: true
additionalProperties: false
ReshopErrorResponse:
type: object
properties:
details:
nullable: true
errorCode:
type: string
nullable: true
errorInfo:
type: string
nullable: true
additionalProperties: false
ReshopRequest:
required:
- exchangeLegs
- orderNumber
- productId
type: object
properties:
orderNumber:
minLength: 1
type: string
productId:
type: string
format: uuid
exchangeLegs:
type: array
items:
$ref: '#/components/schemas/ExchangeLeg'
additionalProperties: false
ReshopResponse:
type: object
properties:
orderNumber:
type: string
nullable: true
productId:
type: string
format: uuid
quoteId:
type: string
nullable: true
exchangeItineraryFares:
type: array
items:
$ref: '#/components/schemas/ExchangeItineraryFare'
nullable: true
additionalProperties: false
Segment:
type: object
properties:
airlineLocator:
type: string
nullable: true
arrivalCode:
type: string
nullable: true
arrivalCountry:
type: string
nullable: true
arrivalDateTime:
type: string
format: date-time
arrivalRegion:
type: string
nullable: true
arrivalTerminal:
type: string
nullable: true
availabilitySource:
type: string
nullable: true
bookingClass:
type: string
nullable: true
cabinClassType:
type: string
nullable: true
codeShareDetail:
type: string
nullable: true
connection:
type: boolean
nullable: true
departureCode:
type: string
nullable: true
departureCountry:
type: string
nullable: true
departureDateTime:
type: string
format: date-time
departureRegion:
type: string
nullable: true
departureTerminal:
type: string
nullable: true
distanceKms:
type: integer
format: int32
nullable: true
durationMins:
type: integer
format: int32
nullable: true
equipment:
type: string
nullable: true
flightNumber:
type: string
nullable: true
id:
type: integer
format: int32
isFlown:
type: boolean
nullable: true
marketingCarrier:
type: string
nullable: true
operatingCarrier:
type: string
nullable: true
seatsAvailable:
type: integer
format: int32
nullable: true
statusCode:
type: string
nullable: true
stops:
type: integer
format: int32
nullable: true
technicalStops:
type: array
items:
$ref: '#/components/schemas/TechnicalStop'
nullable: true
additionalProperties: false
TaxElement:
type: object
properties:
amount:
type: number
format: double
code:
type: string
nullable: true
additionalProperties: false
TechnicalStop:
type: object
properties:
airport:
type: string
nullable: true
arrivalDateTime:
type: string
format: date-time
departureDateTime:
type: string
format: date-time
durationMins:
type: integer
format: int32
nullable: true
additionalProperties: false
securitySchemes:
Bearer:
type: apiKey
description: 'JWT Authorization header using the Bearer scheme. Example: "Authorization: Bearer {token}"'
name: Authorization
in: header
security:
- Bearer: [ ]
https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
Expected behavior
instead of object, swagger provider can pick the first matching json specifications for returned responses, or for accepted requests
fallback strategies instead of 'object' ?
Actual behavior
obj
replaces the type in the signature of the method, either response type or parameter type
Known workarounds
build the object externally and pass it as object, if serializer handles it, it should still work
Affected Type Providers
- SwaggerClientProvider (didnt test... not interested)
- [ X] OpenApiClientProvider
Related information
- Operating system
- Branch
- .NET Runtime, CoreCLR or Mono Version
- Performance information, links to performance testing scripts