[BUG][csharp] httpclient: oneOf/anyOf responses throw ArgumentException because FromJson is invoked with HttpContent
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
Research direction
Start in modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache around the AbstractOpenAPISchema handling in ApiClient.ExecAsync. Generate the provided Pets specification with the csharp httpclient library and run the oneOf response reproduction. Done means the generated client returns the Cat instance and no ArgumentException is thrown.
Written by the indexing model from the issue text.
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
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".
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 139
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from OpenAPITools/openapi-generator
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
OpenAPITools/openapi-generator#25154 ·
Maintainers usually reply within 1 day
-
[BUG][Java][Spring] `HttpInterfacesAbstractConfigurator` is not marked `@Generated`Possibly taken @axelray-dev claimed this 1 day ago. OpenIssue: Bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
OpenAPITools/openapi-generator#25121 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
OpenAPITools/openapi-generator#24997 ·
Maintainers usually reply within 1 day
-
[BUG][KOTLIN] Jackson3 option does not discover modules like Jackson2 doesPossibly taken @kdelay claimed this 31 days ago. OpenIssue: Bug
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
OpenAPITools/openapi-generator#24859 ·
Maintainers usually reply within 1 day
-
[BUG][KOTLIN] Fails to compile after updating to 7.25.0 with useJackson3=false useSpringBoot4=trueOpenIssue: Bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
OpenAPITools/openapi-generator#24842 · 1 comment ·
Maintainers usually reply within 1 day
All issues in OpenAPITools/openapi-generator
Similar issues
-
[Bug] Logo style setting missing and `classic` style not applied across multiple platforms (v3.1.0)Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Stirling-Tools/Stirling-PDF#8382 · 1 reaction ·
Maintainers usually reply within 2 days
-
Difficulty 1/5 Under an hour Newbie friendliness 70/100
Maintainers usually reply within 4 days
-
enhancement untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
opensearch-project/sql#5842 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
openhab/openhab-addons#21882 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
YunaiV/ruoyi-vue-pro#1273 ·
Maintainers usually reply within 3 days