.net HttpClient with custom JsonConverter

2019-02-12 02:40发布

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

3条回答
Melony?
2楼-- · 2019-02-12 03:30

May be you would like to use HttpClient.GetStringAsync Method (String)

var response = client.GetStringAsync("api/sites/" + sid);
return JsonConvert.DeserializeObject<PrefsResponse>(response.Result, new  PrefClassJsonConverter());

Or what exactly you want to be more elegant?

查看更多
看我几分像从前
3楼-- · 2019-02-12 03:37

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
               }
             } 
          }
    });
查看更多
我命由我不由天
4楼-- · 2019-02-12 03:40

I was able to add a custom JsonConverter to the default formatters for HttpClient with the following:

MediaTypeFormatterCollection formatters = new MediaTypeFormatterCollection(); 
formatters.JsonFormatter.SerializerSettings.Converters.Add(new MyCustomConverter());


var result = response.Content.ReadAsAsync<T>(formatters).Result;

This seemed to allow you to just add your custom converter to the default converters.

查看更多
登录 后发表回答