2015-04-23 55 views
5

根據請求是成功還是失敗,我們有外部API返回用戶XML或錯誤XML的場景。是否有可能將2種類型的對象傳遞給Restharp?

此刻,我將User POCO傳遞給restsharp並正常工作。但是如果失敗,這個對象是NULL。我們不知道爲什麼它失敗,除非我們手動解析Error XML。

有沒有辦法解決這個問題?

例如

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

在執行上述方法時,API可以返回Error xml對象。如何獲得錯誤對象失敗和用戶成功?

+0

你可能包括不工作的代碼? – svick

+0

是的,請參閱更新 –

+1

我認爲,如果它可以返回錯誤XML或用戶XML,那麼它不會返回'用戶'。服務器開發人員返回兩種不同的XML格式的設計不好。是否有一種返回XML的'Execute'形式?然後,您可以查看XML以查看它是哪種格式,並將其反序列化爲'用戶'或'錯誤'對象。 –

回答

4

這是可能的,雖然代碼有點難看。 RestSharp允許你指定你自己的XML解串器,所以我們需要這樣做才能做到這一點。

不過,首先,您需要用一個ErrorUser(我做到了通用的,所以它的工作原理的不僅僅是用戶)可存儲的數據類型:

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

這樣的想法是,現在當你執行的要求,你問RestSharp爲Result<User>,而不是僅僅一個User,即:

現在,這裏的反序列化所需的魔法或者一個ErrorUser。這是一個繼承自RestSharp的XmlDeserializer的自定義反序列化器。警告:該代碼根本沒有經過測試,但它可以指示您朝着正確的方向發展。

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

那麼你會連線這一切是這樣的:

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... 
} 
相關問題