Mike Ruhlin Mike Ruhlin - 4 months ago 20
JSON Question

.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;
}

Answer

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
               }
             } 
          }
    });