2012-12-17 50 views
13

我正在使用.NET的HttpClient向WebAPI发出请求,返回一些JSON数据,需要在客户端一点点的自定义反序列化。为此,我制作了自己的JsonConverter,但我无法弄清楚如何使ReadAsAsync<T>方法获得转换器的存在。.net HttpClient与自定义JsonConverter

我已经解决了我的问题,现在使用ReadAsStringAsync来读取响应,然后将该字符串传递给JsonConvert.DeserializeObject,但似乎应该有一个更优雅的解决方案。

这里是我的代码:

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

这是我能做的最好的,或者是有一些更优雅的方式?

这里就是我创建HttpClient的同时,如果这就是我需要把它挂:

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

回答

13

您可以用转换器的JsonMediaTypeFormatter名单将由ReadAsAsync<T>被用来传递JsonSerializerSettings

var obj = await result.Content.ReadAsAsync<refsResponse>(
    new[] {new JsonMediaTypeFormatter { 
      SerializerSettings = new JsonSerializerSettings { 
       Converters = new List<JsonConverter> { 
       //list of your converters 
       } 
      } 
      } 
    }); 
+1

我不知道JSON.Net有它自己的转换器的概念!所以现在我们有三件事可以做同样的工作。派生的HttpContent类,派生的MediaTypeFormatters和派生的JsonConverter .... –

+0

这就是我正在寻找。最终,我会尽我所能,因为我还需要将响应缓存在磁盘上,以防未来请求发生故障。 –

+0

太棒了!我需要定制一些其他的JSON.NET设置,这是我的谜题的缺失:) –

1

可能是你想用HttpClient.GetStringAsync Method (String)

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

或者究竟你想要更优雅?

+0

这肯定比传递一个嵌套的初始化器到'Content.ReadAsAsync()'更优雅。唯一的缺点可能是将流读取到一个字符串中,这对于不是很大的json数据包来说是不错的。我在代码编辑器窗口出来后以这种方式更改了我的代码,并且没有任何格式可以帮助它。 –

1

我能够自定义JsonConverter添加到默认格式化为HttpClient与以下内容:

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


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

这似乎允许您只需将您的自定义转换器添加到默认转换器。

相关问题