2013-03-07 31 views
4

我在.net 4.5中使用了这种新技术,我想查看这个调用的代码,以及如何控制我的异步调用的错误或响应。 该通话工作正常,我需要完全控制从我的服务返回的可能的错误。在MVC4上使用HttpClient进行异步调用

这是我的代码:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Newtonsoft.Json; 

namespace TwitterClientMVC.Controllers 
{ 
    public class Tweets 
    { 
     public Tweet[] results; 
    } 

    public class Tweet 
    { 
     [JsonProperty("from_user")] 
     public string UserName { get; set; } 

     [JsonProperty("text")] 
     public string TweetText { get; set; } 
    } 
} 

public async Task<ActionResult> Index() 
{            
    Tweets model = null; 

    HttpClient client = new HttpClient(); 

    HttpResponseMessage response = await client.GetAsync("http://mywebapiservice"); 

    response.EnsureSuccessStatusCode(); 

    model = JsonConvert.DeserializeObject<Tweets>(response.Content.ReadAsStringAsync().Result); 

    return View(model.results);    
} 

难道这更好的方式来做到这一点?或者我错过了什么? 谢谢

我重构它,这种方法是异步吗?

public async Task<ActionResult> Index() 
    { 
     Tweets model = null; 
     using (HttpClient httpclient = new HttpClient()) 
     { 
      model = JsonConvert.DeserializeObject<Tweets>(
       await httpclient.GetStringAsync("http://search.twitter.com/search.json?q=pluralsight") 
      ); 
     } 
     return View(model.results); 
    } 

回答

5

这是更好的方式来做到这一点?

如果远程服务返回的状态码不是2xx,则response.EnsureSuccessStatusCode();会引发异常。所以,你可能要代替,如果你想自己处理错误使用IsSuccessStatusCode属性:

public async Task<ActionResult> Index() 
{            
    using (HttpClient client = new HttpClient()) 
    { 
     var response = await client.GetAsync("http://mywebapiservice"); 

     string content = await response.Content.ReadAsStringAsync(); 
     if (response.IsSuccessStatusCode) 
     { 
      var model = JsonConvert.DeserializeObject<Tweets>(content); 
      return View(model.results);    
     } 

     // an error occurred => here you could log the content returned by the remote server 
     return Content("An error occurred: " + content); 
    } 
} 
+0

对不起,我还有一个问题,如果这个方法真的是异步的,我怎么能确保在DeserializeObject的时刻,该Web服务已完成? – rgx71 2013-03-07 16:49:59

+0

我已经更新了我的答案。你应该使用'string content = await response.Content.ReadAsStringAsync();'。这将确保在执行到达“DeserializeObject”调用时,客户端已经完成执行请求并读取结果。我原来的代码是同步和阻塞的,因为我在读取的内容中调用了'.Result'属性。这意味着它也保证了执行已经完成,但是它是同步的。最好使用'await',这是真正的异步处理。 – 2013-03-07 16:51:34

+0

谢谢,所以我们需要在GetAsync调用中以及在使用ReadAsStringAsync时使用它。什么IsSuccessStatusCode?那一刻,我们确定电话已完成? – rgx71 2013-03-07 17:11:42