2011-01-20 8 views
6

का उपयोग कर मैं बहुत भयानक WCF बाकी स्टार्टर किट में प्रदान की HttpClient उपयोग कर रहा हूँ अनुरोध।जेनेरिक पोस्ट Microsoft.HttpClient और HttpContentExtensions

public UserValidateResponse Validate() 
{ 
    HttpClient client = new HttpClient(baseUrl); 

    HttpMultipartMimeForm form = new HttpMultipartMimeForm(); 
    form.Add("app_key", this.AppKey); 
    form.Add("user_key", this.UserKey); 
    HttpResponseMessage response = client.Post("user.validate", form.CreateHttpContent()); 

    return response.Content.ReadAsXmlSerializable<UserValidateResponse>(); 
} 

मैं एक अच्छा सामान्य GetRequest विधि है कि इस तरह दिखता है:: मैं निम्न विधि कि HelloTxt एपीआई के खिलाफ काम कर रहा है है

public T GetRequest<T>(string query) 
{ 
    HttpClient client = new HttpClient(baseUrl); 
    client.DefaultHeaders.UserAgent.AddString(@"http://www.simply-watches.co.uk/"); 

    HttpResponseMessage response = client.Get(query); 
    response.EnsureStatusIsSuccessful(); 

    T data = default(T); 
    try 
    { 
     data = response.Content.ReadAsXmlSerializable<T>(); 
     return data; 
    } 
    catch (Exception ex) 
    { 
     Console.Write(String.Format("{0}: {1}", ex.Message, ex.InnerException.Message)); 
    } 

    return data; 
} 

जिनमें से लाभ यह है कि आप इसे टी से पारित सकता है

public List<User> GetUsers(int deptid) 
{ 
    string query = String.Format("department.getUsers?api_key={0}&dept_id={1}", this.APIKey, deptId); 

    return GetRequest<List<User>>(query); 
} 

मैं अब, एक ही सामान्य शैली POST पद्धति करना चाहते हैं के बजाय प्राप्त और मुझे यकीन है कि मैं HttpContentExtensions उपयोग कर सकते हैं, लेकिन मैं च नहीं कर सकते हैं: इस यादृच्छिक उदाहरण के अनुसार प्रतिक्रिया प्रकार के रूप में अनुरोध को HttpMultipartMimeForm में बदलने के तरीके को देखें।

public T PostRequest<K, T>(string query, K request) 
{ 
    HttpClient client = new HttpClient(baseUrl); 
    // the following line doesn't work! Any suggestions? 
    HttpContent content = HttpContentExtensions.CreateDataContract<K>(request, Encoding.UTF8, "application/x-www-form-urlencoded", typeof(HttpMultipartMimeForm)); 

    HttpResponseMessage response = client.Post(query, content); 
    response.EnsureStatusIsSuccessful(); 

    T data = default(T); 
    try 
    { 
     data = response.Content.ReadAsXmlSerializable<T>(); 
     return data; 
    } 
    catch (Exception ex) 
    { 
     Console.Write(String.Format("{0}: {1}", ex.Message, ex.InnerException.Message)); 
    } 

    return data; 
} 

यह इस तरह कहा जा सकता है:

UserValidateResponse response = PostRequest<UserValidateRequest, UserValidateResponse>("user.validate", new UserValidateRequest(this.AppKey, this.UserKey)); 

यह इस एपीआई के खिलाफ काम करने के लिए है: http://hellotxt.com/developers/documentation यह है कि क्या मैं अब तक है। किसी भी सुझाव का स्वागत है! मैं प्रत्येक पोस्ट के लिए एक अलग रूप परिभाषित कर सकता हूं, लेकिन यह सामान्य रूप से करना अच्छा होगा।

+0

मेरे पास एक ऐसा करने के लिए एक ही रास्ता महसूस प्रतिबिंब का उपयोग करें और एक HttpMultipartMimeForm एक वर्ग के सरल गुणों के आधार पर, या क्रमानुसार वस्तु का निर्माण और उसके बाद प्राप्त करने के लिए है रूट एक्सएमएल नोड के तहत पहले बच्चे। – Junto

उत्तर

2

मैं इस पर मेरे अपने प्रश्न का उत्तर दिया। कोड मेरी .NET wrapper for the HelloTxt API - HelloTxt.NET में देखा जा सकता है, और इसके बाद के संस्करण मेरी टिप्पणी के अनुसार, अनुरोध वस्तु गुण बाहर काम करने के प्रतिबिंब का उपयोग करता है, और मूल्यों के साथ एक HttpMultipartMimeForm() भरता है, जबकि वर्ग गुणों पर Required डेटा annotions जाँच।

प्रश्न में कोड है:

/// <summary> 
/// Generic post request. 
/// </summary> 
/// <typeparam name="K">Request Type</typeparam> 
/// <typeparam name="T">Response Type</typeparam> 
/// <param name="query">e.g. user.validate</param> 
/// <param name="request">The Request</param> 
/// <returns></returns> 
public T PostRequest<K, T>(string query, K request) 
{ 
    using (var client = GetDefaultClient()) 
    { 
     // build form data post 
     HttpMultipartMimeForm form = CreateMimeForm<K>(request); 

     // call method 
     using (HttpResponseMessage response = client.Post(query, form.CreateHttpContent())) 
     { 
      response.EnsureStatusIsSuccessful(); 
      return response.Content.ReadAsXmlSerializable<T>(); 
     } 
    } 
} 

/// <summary> 
/// Builds a HttpMultipartMimeForm from a request object 
/// </summary> 
/// <typeparam name="T"></typeparam> 
/// <param name="request"></param> 
/// <returns></returns> 
public HttpMultipartMimeForm CreateMimeForm<T>(T request) 
{ 
    HttpMultipartMimeForm form = new HttpMultipartMimeForm(); 

    Type type = request.GetType(); 
    PropertyInfo[] properties = type.GetProperties(); 
    foreach (PropertyInfo property in properties) 
    { 
     foreach (Attribute attribute in property.GetCustomAttributes(true)) 
     { 
      RequiredAttribute requiredAttribute = attribute as RequiredAttribute; 
      if (requiredAttribute != null) 
      { 
       if (!requiredAttribute.IsValid(property.GetValue(request, null))) 
       { 
        //Console.WriteLine("{0} [type = {1}] [value = {2}]", property.Name, property.PropertyType, property.GetValue(property, null)); 
        throw new ValidationException(String.Format("{0} [type = {1}] requires a valid value", property.Name, property.PropertyType)); 
       } 
      } 
     } 

     if (property.PropertyType == typeof(FileInfo)) 
     { 
      FileInfo fi = (FileInfo)property.GetValue(request, null); 
      HttpFormFile file = new HttpFormFile(); 
      file.Content = HttpContent.Create(fi, "application/octet-stream"); 
      file.FileName = fi.Name; 
      file.Name = "image"; 

      form.Files.Add(file); 
     } 
     else 
     { 
      form.Add(property.Name, String.Format("{0}", property.GetValue(request, null))); 
     } 
    } 

    return form; 
}