【问题标题】:.net HttpClient with custom JsonConverter.net HttpClient 与自定义 JsonConverter
【发布时间】:2012-12-17 13:54:13
【问题描述】:

我正在使用 .NET 的 HttpClient 向 WebAPI 发出请求,该 WebAPI 返回一些 JSON 数据,需要在客户端进行一些自定义反序列化。为此,我创建了自己的JsonConverter,但我不知道如何让ReadAsAsync<T> 方法获取转换器的存在。

我现在已经解决了我的问题,方法是使用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;
    }

【问题讨论】:

    标签: .net json asp.net-web-api dotnet-httpclient


    【解决方案1】:

    您可以将带有转换器列表的JsonSerializerSettings 传递给JsonMediaTypeFormatterReadAsAsync&lt;T&gt; 将使用它:

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

    【讨论】:

    • 我不知道 JSON.Net 有它自己的转换器概念!所以现在我们有了三样东西可以做同样的工作。派生的 HttpContent 类、派生的 MediaTypeFormatters 和派生的 JsonConverter....
    • 这就是我要找的。最终,我将使用我最初拥有的内容,因为我还需要在磁盘上缓存响应,以防将来请求发生故障转移。
    • 太棒了!我需要自定义一些其他 JSON.NET 设置,而这对我来说是缺失的部分:)
    • @filip-w 有没有办法让备用序列化程序成为默认值(即不必作为参数传入)?
    • 在 WebAPi 中配置全局 json 转换器很容易,但在客户端应用程序中,使用 HttpClient 我找不到简单的方法。问题是关于阅读响应,但是POSTing 请求呢?我必须应用 2 个自定义格式化程序,我该怎么做?
    【解决方案2】:

    您可能想使用HttpClient.GetStringAsync Method (String)

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

    或者你到底想要什么更优雅?

    【讨论】:

    • 这绝对比将大量嵌套初始化器传递给Content.ReadAsAsync() 更优雅。唯一的缺点可能是将流读入一个字符串,这对于不是很大的 json 数据包来说已经足够了。在代码退出代码编辑器窗口后,我以这种方式更改了我的代码,并且没有任何格式可以帮助它。
    【解决方案3】:

    我能够使用以下内容将自定义 JsonConverter 添加到 HttpClient 的默认格式化程序:

    MediaTypeFormatterCollection formatters = new MediaTypeFormatterCollection(); 
    formatters.JsonFormatter.SerializerSettings.Converters.Add(new MyCustomConverter());
    
    
    var result = response.Content.ReadAsAsync<T>(formatters).Result;
    

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

    【讨论】:

    • 使用httpclient.PostAsJson()时会怎样?如何传递自定义格式化程序?
    猜你喜欢
    • 1970-01-01
    • 2016-12-31
    • 2021-05-05
    • 1970-01-01
    • 2017-09-08
    • 2014-09-25
    • 2014-08-28
    • 2014-10-09
    • 1970-01-01
    相关资源
    最近更新 更多