2015-04-23 15 views
5

Harici API'nin, isteğin başarılı veya başarısız olup olmadığına bağlı olarak Kullanıcı XML'i veya Hata XML'i döndürdüğü bir senaryoya sahibiz.2 tip nesneyi Restsharp'a geçirmek mümkün mü?

Şu anda Kullanıcı POCO'yu restharmpara geçiriyorum ve iyi çalışıyor. Ama başarısız olursa, bu nesne NULL. Hata XML'i el ile ayrıştırmadıkça neden başarısız olduğunu bilemeyiz.

Bu, geçici bir çözüm yolu var mı?

örn.

var restClient = new RestClient(baseURL); 
var request = new RestRequest(uri); 
request.Method = Method.POST; 
var response = restClient.Execute<User>(request); 

Yukarıdaki yöntemin yürütülmesi üzerine API, Hata xml nesnesini döndürebilir. Başarısız kullanıcı ve hata durumunda nasıl bir hata alıyorum?

+0

sen çalışmıyor kod içeren olabilir mi? – svick

+0

Evet, lütfen bkz. Güncelleme –

+1

Hata XML'i veya Kullanıcı XML'i döndürebiliyorsa, o zaman 'User' döndürmüyor. İki farklı XML biçimini döndürmek için sunucu geliştiricileri tarafında kötü tasarım. XML döndüren bir "Execute" biçimi var mı? Sonra hangi formatta olduğunu görmek için XML'e bakabilir ve 'User' veya 'Error' nesnelerine serpiştirebilirsiniz. –

cevap

4

Bu, kod biraz çirkin olsa da, bu mümkündür. RestSharp, kendi XML deserializer'ınızı belirtmenize izin verir, bu yüzden bu işi yapmak için bunu yapmamız gerekecek. Şimdi,

Yani fikir
public class Result<T> 
{ 
    public T Data { get; set; } 
    public Error Error { get; set; } 
} 

:

Ancak öncelikle, ya bir Error veya User (Ben jenerik o daha adil Kullanıcılar için çalışır böylece yapılmış) saklayabilir bir veri türü gerek Eğer istek yürütebilir zaman, sen yani sadece User yerine Result<User> için RestSharp soruyorum:

Şimdi burada da serisini gerekli sihirli ya bir Error veya User. RestSharp'ın XmlDeserializer'dan devraldığı özel bir desperizatör. Uyarı: Bu kod hiç test edilmemiştir, ancak umarım sizi doğru yönde gösterebilir.

public class XmlResultDeserializer : XmlDeserializer 
{ 
    public override T Deserialize<T>(IRestResponse response) 
    { 
     if (!typeof(T).IsGenericType || typeof(T).GetGenericTypeDefinition() != typeof(Result<>)) 
      return base.Deserialize<T>(response); 

     // Determine whether the response contains an error or normal data. 
     var doc = XDocument.Parse(response.Content); 
     var result = Activator.CreateInstance<T>(); 
     if (doc.Root != null && doc.Root.Name == "Error") 
     { 
      // It's an error 
      var error = base.Deserialize<Error>(response); 
      var errorProperty = result.GetType().GetProperty("Error"); 
      errorProperty.SetValue(result, error); 
     } 
     else 
     { 
      // It's just normal data 
      var innerType = typeof(T).GetGenericArguments()[0]; 
      var deserializeMethod = typeof(XmlDeserializer) 
       .GetMethod("Deserialize", new[] { typeof(IRestResponse) }) 
       .MakeGenericMethod(innerType); 
      var data = deserializeMethod.Invoke(this, new object[] { response }); 

      var dataProperty = result.GetType().GetProperty("Data"); 
      dataProperty.SetValue(result, data); 
     } 
     return result; 
    } 
} 

Sonra böyle hepsini kadar Tel olacaktır:

var restClient = new RestClient(baseURL); 
client.AddHandler("application/xml", new XmlResultDeserializer()); 
var request = new RestRequest(uri); 
request.Method = Method.POST; 
var result = restClient.Execute<Result<User>>(request); 
if (response.Data.Data != null) 
{ 
    var user = response.Data.Data; 
    // Do something with the user... 
} 
else if (response.Data.Error != null) 
{ 
    var error = response.Data.Error; 
    // Handle error... 
} 
İlgili konular