Search code examples
jsonrefit

Call API using Refit and deserialize to dynamic


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?


Solution

  • 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.