OpenAPITools / OpenAPITools/openapi-generator

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

Open
#23,046 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the C# generichost modelOneOf.mustache or equivalent template identified in the issue, and inspect how oneOf model constructors are emitted. Generate the provided minimal OpenAPI spec and verify from a separate consuming project that the generated constructors are public and accessible.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
devtools
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.