.NET HttpClient的自定义JsonConverter自定义、NET、HttpClient、JsonConverter

2023-09-04 00:31:11 作者:Resign (认命)

我使用.NET的HttpClient的发出请求到的WebAPI返回,需要自定义反序列化在客户的身边一点点一些JSON数据。为此,我做了我自己的 JsonConverter ,但我无法弄清楚如何有 ReadAsAsync< T> 方法拿起变换器的存在。

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

下面是我的code:

 公共prefsResponse GETALL preFS(字符串SID){
    HttpClient的客户端= CreateHttpClient(空,SID);
    VAR响应= client.GetAsync(API /网站/+ SID)。结果;

    // TODO:找到一个方法来挂钩的自定义转换器,这个...
    //返回response.Content.ReadAsAsync< prefsResponse>()结果;

    VAR stringResult = response.Content.ReadAsStringAsync()结果。

    返回JsonConvert.DeserializeObject< prefsResponse>(stringResult,新的prefClassJsonConverter());
}
 

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

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

 私人HttpClient的CreateHttpClient(CommandContext CTX,串SID){
        VAR饼干=新的CookieContainer();

        VAR处理器=新HttpClientHandler {
            的CookieContainer =饼干,
            UseCookies = TRUE,
            UseDefaultCredentials = FALSE
        };

        //添加身份饼干:
        如果(CTX = NULL和放大器;!&安培;!ctx.UserExecuting.IsAnonymous){
            字符串username =的String.Format({0}({1}),ctx.RequestingUser.UserName,ctx.UserExecuting.Key);
            cookies.Add(新的Cookie(__ userIdCookieName,用户名));
            cookies.Add(新的Cookie(__ sidCookieName,SID));
            cookies.Add(新的Cookie(__ hashCookieName,
                                   GenerateHash(用户名,prefs.Instance.Url prefs.SharedSecret)));
        }

        VAR的客户=新的HttpClient(处理){
            BaseAddress = _ prefServerBaseUrl
        };

        client.DefaultRequestHeaders.Accept.Add(新MediaTypeWithQualityHeaderValue(应用/ JSON));



        返回客户端;
    }
 
netclient.dll下载 netclient.dll文件下载 当易网

解决方案

您可以通过 JsonSerializerSettings 您转换器的列表 JsonMediaTypeFormatter 将使用由 ReadAsAsync< T>

  VAR OBJ =等待result.Content.ReadAsAsync< refsResponse>(
    新的[] {新JsonMediaTypeFormatter {
          SerializerSettings =新JsonSerializerSettings {
              转换器=新的名单,其中,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;
    }

解决方案

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