2013-01-08 30 views
2

我有一种情况,我必须在catch声明中提取响应(HttpResponseMessage),但我认为无法完成(在catch中使用await)。 此外,如果我抓到后,HttpResponseMessage消息得到“处置”。 代码:如何从HttpRequestException中获取JSON错误消息

private async void MakeHttpClientPostRequest() 
{ 
    HttpResponseMessage response = null; 
    try 
    { 
     HttpClient httpClient = new HttpClient(); 
     httpClient.Timeout = TimeSpan.FromSeconds(15); 
     HttpContent httpContent = null; 
     if (postJSON != null) 
     { 
      httpContent = new StringContent(postJSON); 
      httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 
     } 

     response = await httpClient.PostAsync(url, httpContent); 
     if (response != null) 
     { 
      response.EnsureSuccessStatusCode(); 
      netResults = await response.Content.ReadAsStringAsync(); 
     } 

     if (this.convertedType != null) 
     { 
      MemoryStream assetReader = GetMemoryStreamFromString(netResults); 
      assetReader.Position = 0; 
      object value = fromJSON(assetReader, this.convertedType); 
      networkReqSuccessWithObjectCallback(this, value); 
     } 
     else 
     { 
      //Return netResult as string. 
      networkReqSuccessWithStringCallback(this, netResults); 
     } 
    } 

    catch (TaskCanceledException) 
    { 
     ErrorException ee = null; 
     ee = new ErrorException("RequestTimeOut"); 
     NotifyNetworkDelegates(ee); 
    } 
    catch (HttpRequestException ex) 
    { 
     //HERE I have to extract the JSON string send by the server 
    } 
    catch (Exception) 
    { 
    } 
} 

这里可以做些什么?


前一种方法使用HttpWebRequest更新:

public void MakePostWebRequest() 
{ 
    //WebCalls using HttpWebrequest. 
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); 
    request.CookieContainer = new CookieContainer(); 
    request.ContentType = "application/json"; 
    request.Method = "POST"; 
    requestState = RequestState.ERequestStarted; 
    asyncResult = request.BeginGetRequestStream(new AsyncCallback(GetRequestStream), request); 
} 


private void GetRequestStream(IAsyncResult asyncResult) 
{ 
    HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState; 
    { 
     try 
     { 
      Stream requestStream = request.EndGetRequestStream(asyncResult); 
      if (request != null) 
      { 
       using (requestStream) 
       { 
        StreamWriter writer = new StreamWriter(requestStream); 
        writer.Write(postJSON); 
        writer.Flush(); 
       } 
      } 
     } 
     catch (WebException we) 
     { 
     } 
    } 
} 

private void GetResponseStream(IAsyncResult asyncResult) 
{ 
    requestState = RequestState.EResponseStream; 

    HttpWebRequest request = asyncResult.AsyncState as HttpWebRequest; 
    HttpWebResponse response; 
    try 
    { 
     response = (HttpWebResponse)request.EndGetResponse(asyncResult); 
     using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
     { 
      netResults = reader.ReadToEnd(); 
     } 
     requestState = RequestState.ERequestCompleted; 
    } 
    catch (WebException we) 
    { 
     // failure 
     ErrorException ee = null; 
     response = we.Response as HttpWebResponse; 
     if (response != null) 
     { 
      using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
      { 
       //HERE I'm getting the json error message 
       netResults = reader.ReadToEnd(); 
      } 
     } 
    } 
    catch (Exception e) 
    { 
     networkReqFailedCallback(this, e); 
    } 
} 
+1

你可以尝试使用finally块(http://msdn.microsoft.com/en-us/library/zwc8s4fz(v=vs.80).aspx) – prthrokz

+0

不能在最后完成。 – Suny

+1

如果你使用'await',你为什么得到c#-4.0标签? –

回答

8

我强烈怀疑的问题是,例外是实际上您的通话抛向EnsureSuccessStatusCode,其documentation包含:

如果内容不为空,则此方法也将调用Dispose以免费托管和非托管资源。

基本上,听起来像你不应该使用该方法来确定成功或失败,如果你需要失败的内容。

只要自己检查状态代码,并根据该代码适当地使用内容。请注意,如果请求失败,您的catch块response可能很容易为空。

+1

我正要发布相同的答案。 – selbie

+1

可能的解决方案可以使用HttpResponseMessage.IsSuccessStatusCode(),它返回一个布尔值。 – RolandoCC

1

这样做的正确方法是try块本身

try{ 
    ... 
response = await httpClient.PostAsync(url, httpContent); 
netResults = await response.Content.ReadAsStringAsync(); 
//do something with the result 
} 
catch(HttpRequestException ex) 
{ 
// catch any exception here 
} 

catch块用于处理异常情况然后如果需要重新推出它们,应该避免做其他事情。

+0

检查我更新的问题。 – Suny

+0

我目前还不清楚你的意图。从你的更新中,我想你想要读取异常信息,使用Ex实例和Message,StackTrace等属性。 – prthrokz

+0

对于阅读JSON响应在C#中使用Json.Net库(http://json.codeplex.com/)特别是DeserializeObject (netResults)其中netResults是用于保存响应的代码中的变量 – prthrokz

0

只有在远程服务器实际响应的情况下,响应才可用。如果响应是null(正如我的理解,这是你的情况),这意味着由于某些原因,请求没有传递或没有收到响应(不会改变哪个响应 - 与代码200(OK)或任何其他代码(错误))。请检查错误代码(we.Status)。确保它等于WebExceptionStatus.ProtocolError(即服务器响应错误);否则,会发生一些其他错误,并且响应应该不可用。

相关问题