Skip to content

[BUG][csharp] OneOf model constructors generated as internal, inaccessible from consuming projects #23046

@MartinArltBayoo

Description

@MartinArltBayoo

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

When generating a C# client with the csharp generator, model classes that represent oneOf schemas (e.g., a dynamic metadata value that can be a String, number, boolean, or date-time) have all their constructors generated with internal visibility. This means consuming projects that reference the generated client library cannot construct instances of these types.
The only workarounds from a consuming assembly are:
• Using [UnsafeAccessor] (.NET 8+) to bypass accessibility, which is a low-level runtime hack
• Using reflection via Activator.CreateInstance with BindingFlags.NonPublic
• Adding a public parameterless constructor manually in the partial class extension file inside the generated project
None of these are acceptable for a public API surface. The constructors should be public.

openapi-generator version

OpenAPI Generator used via the generator referenced in the auto-generated file header:
Generated by: https://github.com/openapitools/openapi-generator.git

OPENAPI_GENERATOR_VERSION=7.20.0

OpenAPI document version: 1.5.0

OpenAPI declaration file content or url

Minimal spec to reproduce:

openapi: 3.0.3
info:
  title: Minimal repro
  version: 1.0.0
paths:
  /upload:
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InitiateUploadRequest'
      responses:
        '200':
          description: OK
components:
  schemas:
    InitiateUploadRequest:
      type: object
      properties:
        dynamicMetadata:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/DynamicMetadataValue'
    DynamicMetadataValue:
      oneOf:
        - type: string
        - type: number
        - type: boolean
        - type: string
          format: date-time
Generation Details
Language: csharp
Library: generichost
Steps to reproduce
  1. Generate a C# client library from the spec above using the csharp generator with the generichost library.
  2. Create a separate consuming project that references the generated library.
  3. Attempt to construct a DynamicMetadataValue instance from the consuming project:
// All of these fail with CS0122: inaccessible due to protection level
var val1 = new DynamicMetadataValue("test");
var val2 = new DynamicMetadataValue(42m);
var val3 = new DynamicMetadataValue(true);

// Object initializer also fails (no public parameterless constructor)
var val4 = new DynamicMetadataValue { String = "test" };

Actual output: All constructors are generated as internal:

internal InitiateUploadRequestDynamicMetadataValue(string @string)
{
    String = @string;
    OnCreated();
}

internal InitiateUploadRequestDynamicMetadataValue(decimal @decimal)
{
    Decimal = @decimal;
    OnCreated();
}

// ... same for bool and DateTimeOffset

Expected output: Constructors should be public:

public InitiateUploadRequestDynamicMetadataValue(string @string)
{
    String = @string;
    OnCreated();
}
Related issues/PRs

I did not find any related issues.

Suggest a fix

In the C# generichost template for oneOf models, the constructor visibility modifier should be changed from internal to public. The relevant template is likely in the modelOneOf.mustache or equivalent template file where the constructors are emitted. The visibility keyword just needs to be switched from internal to public.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions