2012-12-17 10 views
13

Ich verwende .NET HttpClient, um Anforderungen an eine WebAPI zu stellen, die einige JSON-Daten zurückgibt, die ein wenig benutzerdefinierte Deserialisierung auf der Clientseite erfordert. Dafür habe ich meine eigene JsonConverter gemacht, aber ich kann nicht herausfinden, wie man die ReadAsAsync<T> Methode die Existenz des Konverters aufheben lässt..net HttpClient mit benutzerdefiniertem JsonConverter

Ich habe mein Problem für jetzt mit ReadAsStringAsync gelöst, um die Antwort zu lesen, dann übergebe diese Zeichenfolge an JsonConvert.DeserializeObject, aber es scheint, als sollte es eine elegantere Lösung geben.

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

Ist dies das Beste, was ich tun kann, oder gibt es eine elegantere Möglichkeit?

Hier ist, wo ich die Httpclient auch bin zu schaffen, wenn es das ist, wo ich es brauche, um hook 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; 
    } 

Antwort

13

Sie können die JsonSerializerSettings mit der Liste Ihrer Wandler zum JsonMediaTypeFormatter passieren, die von ReadAsAsync<T> verwendet wird:

dh

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

Ich hatte keine Ahnung JSON.Net hatte seine eigene Vorstellung von Konvertern! So, jetzt haben wir drei Dinge, die den gleichen Job machen können. Abgeleitete HttpContent-Klassen, abgeleitete MediaTypeFormatters und abgeleitete JsonConverter .... –

+0

Dies ist, was ich gesucht habe. Letztendlich gehe ich mit dem, was ich ursprünglich hatte, da ich auch die Antwort auf der Festplatte im Cache speichern muss bei Failovers für zukünftige Anfragen. –

+0

Wunderbar! Ich musste einige andere JSON.NET-Einstellungen anpassen und dies war das fehlende Teil des Puzzles für mich :) –

1

Mai werden Sie HttpClient.GetStringAsync Method (String)

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

verwenden möchten oder was Sie genau möchte eleganter sein?

+0

Dies ist definitiv eleganter, als eine Hölle von verschachtelten Initialisierer an die 'Content.ReadAsAsync()' zu übergeben. Der einzige Nachteil ist wahrscheinlich, den Stream in eine Zeichenfolge zu lesen, die mehr als gut für nicht sehr große JSON-Pakete ist. Ich habe meinen Code auf diese Weise geändert, nachdem das Code-Editor-Fenster ausging, und keine Formatierung hilft dabei. –

1

konnte ich eine benutzerdefinierte JsonConverter auf die Standardformatierer hinzufügen für HttpClient mit den folgenden:

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


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

Dies schien Ihnen zu erlauben, nur Ihren benutzerdefinierten Konverter zu den Standardkonverter.

Verwandte Themen