2012-08-24 20 views
6

我使用HttpClient来调用我的MVC 4 web api。在我的Web API调用中,它返回一个域对象。如果出现任何问题,将在服务器上抛出一个HttpResponseException,并附带自定义消息。HttpClient不报告从web API返回的异常

[System.Web.Http.HttpGet] 
    public Person Person(string loginName) 
    { 
     Person person = _profileRepository.GetPersonByEmail(loginName); 
     if (person == null) 
      throw new HttpResponseException(
     Request.CreateResponse(HttpStatusCode.NotFound, 
       "Person not found by this id: " + id.ToString())); 

     return person; 
    } 

我可以在使用IE F12的响应正文中看到自定义错误消息。但是,当我使用HttpClient调用它时,我没有收到定制的错误消息,只有http代码。 404的“ReasonPhrase”始终为“未找到”,500代码为“内部服务器错误”。

任何想法?如何从Web API发送自定义错误消息,同时保持正常的返回类型为我的域对象?

+0

你正在使用什么Web服务器,IIS或ASP.NET Web服务器? –

+0

我在Win 2008 R2上使用IIS。再次,当我使用浏览器调用它时没关系。 – Calvin

回答

14

(这里把我的答案更好的格式)

是的,我看到了它,但HttpResponseMessage没有一个身体属性。我自己想到:response.Content.ReadAsStringAsync().Result;。示例代码:

public T GetService<T>(string requestUri) 
{ 
    HttpResponseMessage response = _client.GetAsync(requestUri).Result; 
    if(response.IsSuccessStatusCode) 
    { 
     return response.Content.ReadAsAsync<T>().Result; 
    } 
    else 
    { 
     string msg = response.Content.ReadAsStringAsync().Result; 
      throw new Exception(msg); 
    } 
} 
+4

您应该警惕直接从'ReadAsAsync '调用'Result',因为这会导致间歇性线程问题。相反,尝试:'var contentTask = response.Content.ReadAsAsync ();'后面跟着'contentTask.Wait();'然后'return contentTask.Result;' –

+0

感谢您的提示! – Calvin

+2

@Sixto:你能描述线程问题吗? [结果](http://msdn.microsoft.com/en-us/library/vstudio/dd321468(v = vs.110).aspx)文档说:“该属性的get访问器确保异步操作完成在返回之前。“这听起来像是对内置的“Wait”调用。 –

0

自定义错误消息将位于响应的“主体”中。

+0

是的,我看到它,但HttpResponseMessage没有body属性。我自己想了一下:'response.Content.ReadAsStringAsync()。Result;'。示例代码: public T GetService (string requestUri) HttpResponseMessage response = _client.GetAsync(requestUri).Result; if(response.IsSuccessStatusCode) {0122] } else { string msg = response.Content.ReadAsStringAsync()。Result; 抛出新异常(msg); } } – Calvin

+0

其实身体,我的意思是响应的内容。 –

1

我从响应中获取异常时考虑了一些逻辑。

这使得它非常容易提取异常,内部异常,内部异常:)等

public static class HttpResponseMessageExtension 
{ 
    public static async Task<ExceptionResponse> ExceptionResponse(this HttpResponseMessage httpResponseMessage) 
    { 
     string responseContent = await httpResponseMessage.Content.ReadAsStringAsync(); 
     ExceptionResponse exceptionResponse = JsonConvert.DeserializeObject<ExceptionResponse>(responseContent); 
     return exceptionResponse; 
    } 
} 

public class ExceptionResponse 
{ 
    public string Message { get; set; } 
    public string ExceptionMessage { get; set; } 
    public string ExceptionType { get; set; } 
    public string StackTrace { get; set; } 
    public ExceptionResponse InnerException { get; set; } 
} 

完整的讨论见this blog post