[BUG][csharp] httpclient: oneOf/anyOf responses throw ArgumentException because FromJson is invoked with HttpContent
Maintainer thường phản hồi trong vòng 1 ngày
Đá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
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ả
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
-
Generate the client with the command above.
-
Serve
GET /petreturning{"meows": true}withContent-Type: application/jsononhttp://127.0.0.1:18803. -
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
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.
- Có Dockerfile hoặc tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của OpenAPITools/openapi-generator
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
OpenAPITools/openapi-generator#25154 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[BUG][Java][Spring] `HttpInterfacesAbstractConfigurator` is not marked `@Generated`Có thể đã có người làm @axelray-dev đã nhận 3 ngày trước. Đang mởIssue: Bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
OpenAPITools/openapi-generator#25121 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
OpenAPITools/openapi-generator#24997 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[BUG][KOTLIN] Jackson3 option does not discover modules like Jackson2 doesCó thể đã có người làm @kdelay đã nhận 33 ngày trước. Đang mởIssue: Bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
OpenAPITools/openapi-generator#24859 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Issue: Bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
OpenAPITools/openapi-generator#24816 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của OpenAPITools/openapi-generator
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
liquid-java/liquidjava#373 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
NationalSecurityAgency/ghidra#9748 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
Maintainer thường phản hồi trong vòng 1 ngày
-
spring-mcp-tools
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
explyt/spring-plugin#591 ·
Maintainer thường phản hồi trong vòng 1 ngày