-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
oneOf is not produce the right results for C# generated classes? #2991
Description
When trying to generate an API client for ShipEngine, NSwag is having issues when using oneOf to combine related entities to indicate that the request can have one of the two values. It ends up just bringing in the type for the first value, but the second is never included. Here is the simplified yaml file:
openapi: 3.0.0
info:
title: oneOf bug
version: 1.0
components:
schemas:
se_id:
title: se_id
type: string
calculate_rates_request_body:
title: calculate_rates_request_body
type: object
required:
- shipment_id
- shipment
additionalProperties: false
oneOf:
- $ref: '#/components/schemas/shipment_id_request'
- $ref: '#/components/schemas/shipment_request'
shipment_id_request:
title: shipment_id_request
type: object
additionalProperties: false
properties:
shipment_id:
allOf:
- $ref: '#/components/schemas/se_id'
shipment_request:
title: shipment_request
type: object
additionalProperties: false
properties:
shipment:
allOf:
- $ref: '#/components/schemas/address_validating_shipment'
address_validating_shipment:
title: address_validating_shipment
type: object
required:
- shipment_id
- carrier_id
additionalProperties: false
properties:
shipment_id:
allOf:
- $ref: '#/components/schemas/se_id'
carrier_id:
allOf:
- $ref: '#/components/schemas/se_id'
The C# class generated is the following. Note that the it only contains the base ShipmentId field, and not the second Shipment field which the schema happily supports.
public partial class CalculateRatesRequestBody
{
public string ShipmentId { get; set; }
}
public partial class ShipmentRequest
{
public AddressValidatingShipment Shipment { get; set; }
}
public partial class AddressValidatingShipment
{
public string ShipmentId { get; set; }
public string CarrierId { get; set; }
}What I would have expected to be generated is the following:
public partial class CalculateRatesRequestBody
{
public string ShipmentId { get; set; }
public AddressValidatingShipment Shipment { get; set; }
}
public partial class AddressValidatingShipment
{
public string ShipmentId { get; set; }
public string CarrierId { get; set; }
}If I change it to be allOf rather than oneOf, I get the following which does work. But in reality the spec is correct in saying it's a oneOf and not allOf, because only one can be sent in the request at a time, not all of them:
public partial class CalculateRatesRequestBody : ShipmentIdRequest
{
}
public partial class ShipmentIdRequest
{
public string ShipmentId { get; set; }
}
public partial class ShipmentRequest
{
public AddressValidatingShipment Shipment { get; set; }
}
public partial class AddressValidatingShipment
{
public string ShipmentId { get; set; }
public string CarrierId { get; set; }
}So it seems to me when generating a C# class for this specification, we should really be generating the same schema as the allOf case. Any ideas on the best way to fix this in the code? I assume it's probably in the JsonSchema rendering code, not NSwag itself?