2013-03-07 6 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

이 할 수있는 더 좋은 방법이 있나요?

response.EnsureSuccessStatusCode();은 원격 서비스에서 반환 한 상태 코드가 2xx와 다른 경우 예외가 발생합니다. 그래서 당신은 당신이 오류를 직접 처리하는 대신 경우 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의 순간 , 웹 서비스가 끝났습니까? – rgx71

+0

답변을 업데이트했습니다. 당신은'string content = await response.Content.ReadAsStringAsync();'를 사용해야합니다. 이렇게하면 실행이 DeserializeObject 호출에 도달 할 때까지 클라이언트가 요청 실행을 완료하고 결과를 읽는 것을 보장합니다. 읽은 내용에'.Result' 속성을 호출했기 때문에 원래 코드가 동기 및 차단되었습니다. 즉, 실행이 완료되었지만 동기가 발생했음을 보장합니다. 사실 비동기 처리 인'await'을 사용하는 것이 낫습니다. –

+0

감사합니다. 그래서 우리는 GetAsync 호출에서이를 사용할 필요가 있고 ReadAsStringAsync를 사용할 때도 필요합니다. IsSuccessStatusCode는 어떻습니까? 그 순간 전화가 끝났다고 확신합니까? – rgx71