2012-12-17 23 views
13

साथ मैं नेट के HttpClient उपयोग कर रहा हूँ एक वेबएपीआई कि कुछ 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 और जेसन कनवर्टर व्युत्पन्न .... –

+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()' के लिए नेस्टेड initializers की एक नरक गुजर की तुलना में अधिक सुंदर है। एकमात्र विपक्ष शायद एक स्ट्रिंग में धारा को पढ़ रहा है जो बहुत बड़े जेसन पैकेट के लिए ठीक से अधिक नहीं है। कोड कोड संपादक विंडो के बाहर जाने के बाद मैंने अपना कोड बदल दिया, और कोई प्रारूपण इसके साथ मदद नहीं करता है। –

1

मैं के लिए डिफ़ॉल्ट formatters के लिए एक कस्टम JsonConverter जोड़ने के लिए सक्षम था निम्नलिखित के साथ HttpClient:

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


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

ऐसा लगता है कि आप केवल अपने कस्टम कनवर्टर को जोड़ने के लिए अनुमति देते हैं डिफ़ॉल्ट कन्वर्टर्स।

संबंधित मुद्दे