2

ステートメントでResponse(HttpResponseMessage)を抽出する必要があるのに、( catchでcatch使用して)実行できないと思われる状況があります。awaitまた、キャッチ後に行うと、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

コンテンツがnullでない場合、このメソッドはDisposeを呼び出して、管理対象リソースと管理対象外リソースを解放します。

基本的に、失敗したコンテンツが必要な場合は、その方法を使用して成功または失敗を判断するべきではないように思われます。

自分でステータスコードを確認し、そのコードに基づいてコンテンツを適切に使用してください。リクエストが完全に失敗した場合、 catchブロックでresponseは非常に簡単にnullになる可能性があることに注意してください。

于 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

応答は、リモートサーバーが実際に応答した場合にのみ使用可能にする必要があります。応答がnull(これがあなたの場合であると私が理解したように)である場合、それは何らかの理由で要求が配信されなかったか、応答が受信されなかったことを意味します(どの応答を変更しません-コード200(OK)または他のコード(エラー))。エラーコード(we.Status)を確認してください。それが等しいことを確認しWebExceptionStatus.ProtocolErrorます(つまり、サーバーがエラーで応答しました)。そうしないと、他のエラーが発生し、応答が利用できないはずです。

于 2013-01-08T05:41:14.820 に答える