Call API using Refit and deserialize to dynamic

4.8k views Asked by At

I'm calling a REST service using Refit and I want to deserialize the JSON that is returned as a dynamic type.

I tried defining the interface as

[Get("/foo")]
Task<dynamic> GetFoo();

but the call times out.

I know I can deserialize to a dynamic like this

var mockString = "{ title: { name: 'fred', book: 'job'} }";
dynamic d = JsonConvert.DeserializeObject(mockString);

but I can't figure out what to pass to Refit to get it to do the same.

Another option would be to get Refit to pass the raw JSON back so I can deserialize it myself but I can't see a way to do that either.

Any ideas?

2

There are 2 answers

2
Bennor McCarthy On BEST ANSWER

Refit uses JSON.NET under the hood, so any deserialization that works with that will work with Refit, including dynamic. The interface you have described is exactly right.

Here's a real working example:

public interface IHttpBinApi
{
    [Get("/ip")]
    Task<dynamic> GetIp();
}

var value = await RestService.For<IHttpBinApi>("http://httpbin.org").GetIp();

If you are using iOS and Refit 4+, you might be seeing this bug: https://github.com/paulcbetts/refit/issues/359

As Steven Thewissen has stated, you can use Task<string> as your return type (or Task<HttpResponseMessage>, or even Task<HttpContent>) to receive the raw response and deserialize yourself, but you shouldn't have to -- the whole point of Refit is that it's supposed to save you that hassle.

[UPDATED: 02/2023]

Refit now uses System.Text.Json by default (see the comment below), but the approach here should still work.

1
Steven Thewissen On

You can define your interface to return a string and get the raw JSON that way:

[Get("/foo")]
Task<string> GetFoo();

As described here: https://github.com/paulcbetts/refit#retrieving-the-response