question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

oneOf is not produce the right results for C# generated classes?

See original GitHub issue

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?

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:6
  • Comments:33 (14 by maintainers)

github_iconTop GitHub Comments

3reactions
mladedavcommented, Sep 25, 2020

oneOf can be accomodated by polymorphism. From what I understood here allOf is already supported. anyOf could be potentially supported the same way as oneOf with polymorphism with having different requirements for each class while they are also merged together, but having a validation logic would seem better at that point.

Isn’t this pretty major issue if NSwag doesn’t really work properly with the standard? Can this issue get a bit more traction?

2reactions
davidmotencommented, Mar 25, 2022

We eventually figured out that openapi-generator can generate working code from oneOf elements. It took a couple of days to bump into the right parameters on a revisit (they were a bit hidden in the documentation). Our guy used netcore generator with a targetFramework of net4.7 and all was well.

I also realized that this stackoverflow answer (“replace the oneOf with a reference to an abstract type”) was a viable workaround that might work with generators like this one (it did with openapi-generator java generator).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Protobuf version difference in generated code for std::string ...
For this protofile, I compile it with protoc(3.17.0), I get a utility method in generated Test class to check if str is set...
Read more >
C# class generated with Protoc not deserializing a "Oneof" ...
I have a proto file which contains the below in it message OuterMessage{ oneof instanceOrGroup { string PropertyA = 10; string PropertyB ...
Read more >
C# Generated Code Guide | Protocol Buffers Documentation
This topic describes exactly what C# code the protocol buffer compiler generates for protocol definitions using proto3 syntax.
Read more >
JSON Schema Serializer and Deserializer
This document describes how to use JSON Schema with the Apache Kafka® Java client and console tools. The Confluent Schema Registry based JSON...
Read more >
Using matchers
Matchers into a suite class, you can write an equality assertion in that suite ... The next expression will by default not result...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found