2

我有一种情况,我必须HttpResponseMessage在语句中提取一个 Response(),catch但我认为不能完成(await在 catch 中使用)。另外,如果我在 catch 之后执行此操作,则HttpResponseMessage消息会“已处理”。代码:

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

3 回答 3

9

我强烈怀疑问题是异常实际上是由您的调用引发的EnsureSuccessStatusCode,其文档包含:

如果 Content 不为 null,此方法还将调用 Dispose 以释放托管和非托管资源。

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

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

于 2013-01-08T05:28:07.240 回答
2

这样做的正确方法是在 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
}

捕获块用于处理异常情况。如果需要,请重新抛出,但应避免。

于 2013-01-08T04:38:05.697 回答
0

只有在远程服务器实际响应的情况下才应提供响应。如果 Response 是null(据我所知,这是您的情况),这意味着由于某些原因,请求未交付或未收到响应(不知道哪个响应 - 使用代码 200(OK)或任何其他代码(错误))。请检查错误代码 ( we.Status)。确保它相等WebExceptionStatus.ProtocolError(即服务器响应错误);否则,会发生一些其他错误并且响应不可用。

于 2013-01-08T05:41:14.820 回答