Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.net HttpClient with custom JsonConverter

I'm using .NET's HttpClient to make requests to a WebAPI that returns some JSON data that requires a little bit of custom deserialization on the client's side. For this I've made my own JsonConverter, but I can't figure out how to have the ReadAsAsync<T> method pick up the existence of the converter.

I've solved my problem for now by using ReadAsStringAsync to read the response, then passing that string in to JsonConvert.DeserializeObject, but it seems like there should be a more elegant solution.

Here's my code:

public PrefsResponse GetAllPrefs(string sid) {
    HttpClient client = CreateHttpClient(null, sid);
    var response = client.GetAsync("api/sites/" + sid).Result;

    // TODO : find a way to hook custom converters to this...
    // return response.Content.ReadAsAsync<PrefsResponse>().Result;

    var stringResult = response.Content.ReadAsStringAsync().Result;

    return JsonConvert.DeserializeObject<PrefsResponse>(stringResult, new PrefClassJsonConverter());
}

Is this the best I can do, or is there some more elegant way?

Here's where I'm creating the HttpClient also, if that's where I need to hook it up:

        private HttpClient CreateHttpClient(CommandContext ctx, string sid) {
        var cookies = new CookieContainer();

        var handler = new HttpClientHandler {
            CookieContainer = cookies,
            UseCookies = true,
            UseDefaultCredentials = false
        };

        // Add identity cookies:
        if (ctx != null && !ctx.UserExecuting.IsAnonymous) {
            string userName = String.Format("{0} ({1})", ctx.RequestingUser.UserName, ctx.UserExecuting.Key);
            cookies.Add(new Cookie(__userIdCookieName, userName));
            cookies.Add(new Cookie(__sidCookieName, sid));
            cookies.Add(new Cookie(__hashCookieName,
                                   GenerateHash(userName, Prefs.Instance.UrlPrefs.SharedSecret)));
        }

        var client = new HttpClient(handler) {
            BaseAddress = _prefServerBaseUrl
        };

        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));



        return client;
    }
like image 907
Mike Ruhlin Avatar asked Dec 17 '12 13:12

Mike Ruhlin


1 Answers

You can pass the JsonSerializerSettings with the list of your converters to the JsonMediaTypeFormatter which will be used by ReadAsAsync<T>:

i.e.

var obj = await result.Content.ReadAsAsync<refsResponse>(
    new[] {new JsonMediaTypeFormatter {
          SerializerSettings = new JsonSerializerSettings { 
              Converters = new List<JsonConverter> {
                //list of your converters
               }
             } 
          }
    });
like image 151
Filip W Avatar answered Sep 18 '22 12:09

Filip W