refit icon indicating copy to clipboard operation
refit copied to clipboard

[Bug]: Request builder uses `object` as type parameter for `ToHttpContent`

Open ssandif opened this issue 2 years ago • 1 comments

Describe the bug 🐞

As of .NET 7, using the System.Text.Json source generator no longer falls back to reflection-based serialization: https://learn.microsoft.com/en-us/dotnet/core/compatibility/serialization/7.0/reflection-fallback

Refit accidentally relies on this behavior for serializing JSON request bodies, because it always calls ToHttpContent<object>() (see line 587 in RequestBuilderImplementation)

This causes Refit's generated methods in a .NET 7 project with a JSON request body and source generators to throw an exception like below:

System.NotSupportedException: Metadata for type 'System.Object' was not provided by TypeInfoResolver of type 'YourTypeHere'. If using source generation, ensure that all root types passed to the serializer have been indicated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.

So to summarize, there are two issues:

  1. The fact that Refit always calls ToHttpContent<object>() causes Refit to accidentally use reflection-based serialization on versions prior to .NET 7
  2. On .NET 7, this causes the method calls to fail altogether

Step to reproduce

  1. Create a .NET 7 project
  2. Create a Refit method that uses an ExampleClass (name is arbitrary) parameter as a JSON request body
  3. Create a source generated JsonSerializerContext including ExampleClass, and configure Refit to use it.
  4. Attempting to call that method will cause an exception, because System.Text.Json will treat the parameter as object instead of ExampleClass, and will no longer fall back to reflection

Reproduction repository

No response

Expected behavior

Refit should call ToHttpContent with the correct type parameter, instead of object

Screenshots 🖼️

No response

IDE

Visual Studio 2022

Operating system

No response

Version

No response

Device

No response

ReactiveUI Version

No response

Additional information ℹ️

No response

ssandif avatar Mar 08 '23 19:03 ssandif

Can confirm this in .Net 7 project. This is hitting hard as I'm using JsonDerivedType with source code generation, and it serializes to the wrong type. I'm having to manually create the JsonContent and pass that to the Refit generated code using DIM.

x2764tech avatar May 10 '23 16:05 x2764tech