I have a situation where in I have to extract a Response(HttpResponseMessage) in a catch statement but that I suppose can't be done (using await in catch). Also if i do it after catch , the HttpResponseMessage message gets "Disposed". Code:

 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)
     {
     }
}

What can be done here ?


Update Previous approach using 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);
    }
}
share|improve this question
1  
Can you try using the finally block (msdn.microsoft.com/en-us/library/zwc8s4fz(v=vs.80).aspx) – prthrokz Jan 8 at 4:31
cant be done inside a finally also. – Suny Jan 8 at 4:33
1  
Why have you got the c#-4.0 tag if you're using await? – Jon Skeet Jan 8 at 4:35
2  
@Inder: It's not C# 4.5 either - it's C# 5... – Jon Skeet Jan 8 at 4:38
1  
@Suny: Sure, but you can't use response if it hasn't been assigned a value... – Jon Skeet Jan 8 at 4:48
show 5 more comments

3 Answers

up vote 4 down vote accepted

I strongly suspect the problem is that the exception is actually thrown by your call to EnsureSuccessStatusCode, whose documentation contains:

If the Content is not null, this method will also call Dispose to free managed and unmanaged resources.

Basically it sounds like you shouldn't be using that method to determine the success or failure if you need the content on failure.

Just check the status code yourself, and use the content appropriately based on that code. Note that in your catch block response could very easily be null, if the request failed completely.

share|improve this answer
I was about to post the same answer. – selbie Jan 8 at 5:42
@JonSkeet thanks. – Suny Jan 8 at 5:48

The correct way of doing this is within the try block itself

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 blocks are used to handle exceptional conditions and then rethrow them if required and should be avoided for doing anything else.

share|improve this answer
check my updated question. – Suny Jan 8 at 4:46
I am still unclear about your intent here. From your update, I think you want to read the exception information, use the ex instance and properties like Message, StackTrace etc. – prthrokz Jan 8 at 4:54
For reading Json responses in c# use Json.Net library (json.codeplex.com) specifically the DeserializeObject<T>(netResults) where netResults is the variable in your code used to hold the response – prthrokz Jan 8 at 4:58

Response should be available only in case when a remote server actually responded. If Response is null (as I understood this is your case), it means that because of some reasons the request wasn't delivered or response wasn't received (doesn't metter which response - with code 200 (OK) or any other code (ERROR)). Please check the error code (we.Status). Ensure it is equal WebExceptionStatus.ProtocolError (i.e., the server responded with error); otherwise, some some other error occurred and Response should not be available.

share|improve this answer

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.