Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

[BUG][csharp] httpclient: oneOf/anyOf responses throw ArgumentException because FromJson is invoked with HttpContent

Đã đóng Phù hợp với người mới
#25,079 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@cguldner đang làm issue này rồi.

Từ ngày 1/10/2026.

  • #25080 của @cguldner — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
78/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
csharp
Lĩnh vực
api, tooling

Hướng nghiên cứu

Bắt đầu trong modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache, tại phần xử lý AbstractOpenAPISchema trong ApiClient.ExecAsync. Tạo specification Pets được cung cấp bằng thư viện csharp httpclient và chạy việc tái hiện response oneOf. Hoàn tất khi client được tạo trả về instance Cat và không có ArgumentException nào được ném ra.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Issue: Bug
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

With the csharp generator and --library=httpclient, any operation whose response schema is a oneOf (or anyOf) throws at runtime, even when the server returns a valid response.

After deserializing a successful response, ApiClient.ExecAsync has a special case for AbstractOpenAPISchema types:

object responseData = await deserializer.Deserialize<T>(response).ConfigureAwait(false);

// if the response type is oneOf/anyOf, call FromJSON to deserialize the data
if (typeof(Pets.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
{
    responseData = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
}

FromJson(string jsonString) takes a JSON string, but the code passes response.Content, which is an HttpContent. Because the call goes through reflection it compiles, then fails on every call:

Unhandled exception. System.ArgumentException: Object of type 'System.Net.Http.HttpConnectionResponseContent' cannot be converted to type 'System.String'.
   at System.RuntimeType.CheckValue(Object& value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Pets.Client.ApiClient.ExecAsync[T](HttpRequestMessage req, IReadableConfiguration configuration, CancellationToken cancellationToken)
   at Pets.Client.ApiClient.Exec[T](HttpRequestMessage req, IReadableConfiguration configuration)
   at Pets.Client.ApiClient.Get[T](String path, RequestOptions options, IReadableConfiguration configuration)
   at Pets.Api.DefaultApi.GetPetWithHttpInfo()

This makes every operation with a oneOf/anyOf response unusable with the httpclient library.

openapi-generator version
  • 7.25.0
  • 7.26.0-SNAPSHOT (master, 20261001.032649-175)

Not a recent regression: the same line is in the httpclient ApiClient.mustache at v5.4.0 (csharp-netcore), v6.0.0, v7.0.0, and current master.

OpenAPI declaration file content or url
openapi: 3.0.3
info:
  title: Pets
  version: '1'
paths:
  /pet:
    get:
      operationId: getPet
      responses:
        '200':
          description: A cat or a dog.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Cat'
                  - $ref: '#/components/schemas/Dog'
components:
  schemas:
    Cat:
      type: object
      required: [meows]
      properties:
        meows:
          type: boolean
      additionalProperties: false
    Dog:
      type: object
      required: [barks]
      properties:
        barks:
          type: boolean
      additionalProperties: false

openapi-generator-cli validate -i pets.yaml reports No validation issues detected.

Generation Details
java -jar openapi-generator-cli.jar generate \
  -i pets.yaml \
  -g csharp \
  --library=httpclient \
  -o gen \
  --additional-properties=packageName=Pets

The generated client targets net10.0 and was run on .NET runtime 10.0.12.

Steps to reproduce
  1. Generate the client with the command above.

  2. Serve GET /pet returning {"meows": true} with Content-Type: application/json on http://127.0.0.1:18803.

  3. Run a console program that references the generated project:

    using System;
    using Pets.Api;
    using Pets.Client;
    
    public static class Program
    using Pets.Client;
    
    public static class Program
    {
        public static void Main()
        {
            var api = new DefaultApi(new Configuration { BasePath = "http://127.0.0.1:18803" });
            var pet = api.GetPet();
            Console.WriteLine("OK: " + pet.ActualInstance.GetType().Name);
        }
    }
    

Expected output: OK: Cat

Actual output: the ArgumentException above, thrown from ApiClient.ExecAsync.

Related issues/PRs

I couldn't find an existing report. I searched issues for httpclient FromJson response.Content, HttpConnectionResponseContent cannot be converted, and csharp httpclient oneOf FromJson.

Suggest a fix

The problem is in modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache (line 566 on master):

responseData = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });

Passing the body text fixes it. HttpClient has already buffered the content, so it can be read again:

responseData = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { await response.Content.ReadAsStringAsync().ConfigureAwait(false) });

With this change the reproduction above prints OK: Cat.

Removing the block may also work. The Deserialize<T> call just before it already returns the correct type, because each oneOf/anyOf model has a [JsonConverter(typeof(...JsonConverter))] attribute that Newtonsoft.Json uses.

I only ran oneOf responses. The anyOf claim comes from the code: the branch checks AbstractOpenAPISchema, which both kinds of model inherit from. To keep the issue strictly to what was tested, change "oneOf (or anyOf)" to just "oneOf".

Ngôn ngữ chính
Java
Star
26.8k
Fork
7.7k
Merge trung bình
2 ngày 7 giờ
Pull request đã merge (30 ngày)
148

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của OpenAPITools/openapi-generator

Tất cả issue của OpenAPITools/openapi-generator

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.