2012-12-17 12 views
13

Utilizzo HttpClient di .NET per effettuare richieste a una WebAPI che restituisce alcuni dati JSON che richiedono un po 'di deserializzazione personalizzata dal lato del client. Per questo ho creato il mio JsonConverter, ma non riesco a capire come avere il metodo ReadAsAsync<T> per raccogliere l'esistenza del convertitore..net HttpClient con JsonConverter personalizzato

Ho risolto il problema per ora utilizzando ReadAsStringAsync per leggere la risposta, quindi passare quella stringa in JsonConvert.DeserializeObject, ma sembra che ci dovrebbe essere una soluzione più elegante.

Ecco il mio codice:

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

questo è il meglio che posso fare, o c'è qualche modo più elegante?

Ecco dove sto creando il HttpClient anche, se è lì che ho bisogno di collegarlo:

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

risposta

13

È possibile passare il JsonSerializerSettings con l'elenco dei tuoi convertitori al JsonMediaTypeFormatter che verrà utilizzato da ReadAsAsync<T>:

cioè

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

Non avevo idea che JSON.Net avesse la propria nozione di convertitori! Quindi ora abbiamo tre cose che possono fare lo stesso lavoro. Classi HttpContent derivate, MediaTypeFormatters derivati ​​e derivato JsonConverter .... –

+0

Questo è quello che stavo cercando. In definitiva, sto andando con quello che avevo inizialmente, anche se ho bisogno di memorizzare la risposta sul disco in caso di failover su richieste future. –

+0

Meraviglioso! Avevo bisogno di personalizzare alcune altre impostazioni di JSON.NET e questo era il pezzo mancante del puzzle per me :) –

1

Può essere che si desidera utilizzare HttpClient.GetStringAsync Method (String)

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

O che cosa esattamente si vuoi essere più elegante?

+0

Questo è decisamente più elegante che passare un inferno di inizializzatori nidificati al 'Content.ReadAsAsync()'. L'unico inconveniente è probabilmente la lettura del flusso in una stringa che va benissimo per pacchetti json non molto grandi. Ho cambiato il mio codice in questo modo dopo che è uscito la finestra dell'editor di codice e nessuna formattazione è d'aiuto. –

1

sono stato in grado di aggiungere una consuetudine JsonConverter ai formattatori predefiniti per HttpClient con il seguente:

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


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

Questo sembrava consentirvi di aggiungere il vostro convertitore personalizzato al convertitori predefiniti.

Problemi correlati