6

I have the below code, working as expected (given correct URL etc) as a POST request. Seems I have a problem reading the Status Code (I receive a successful 201, and based on that number I need to continue processing). Any idea how to get the status code?

static async Task CreateConsentAsync(Uri HTTPaddress, ConsentHeaders cconsentHeaders, ConsentBody cconsent)
{
    HttpClient client = new HttpClient();
    
    try
    {
        client.BaseAddress = HTTPaddress;
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
        client.DefaultRequestHeaders.Add("Connection", "keep-alive");
        client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
            
        client.DefaultRequestHeaders.Add("otherHeader", myValue);
        //etc. more headers added, as needed...
    
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, client.BaseAddress);
    
        request.Content = new StringContent(JsonConvert.SerializeObject(cconsent, Formatting.Indented), System.Text.Encoding.UTF8, "application/json");
    
        Console.WriteLine("\r\n" + "POST Request:\r\n" + client.DefaultRequestHeaders + "\r\nBody:\r\n" + JsonConvert.SerializeObject(cconsent, Formatting.Indented) + "\r\n");
                
        await client.SendAsync(request).ContinueWith
        (
            responseTask => 
            {
                Console.WriteLine("Response: {0}", responseTask.Result + "\r\nBody:\r\n" + responseTask.Result.Content.ReadAsStringAsync().Result);
            }
        );
            
        Console.ReadLine();
    }
    catch (Exception e)
    {
        Console.WriteLine("Error in " + e.TargetSite + "\r\n" + e.Message);
        Console.ReadLine();
    }
}
1
  • You're already in an async function, so you don't need to use ContinueWith. Commented Dec 11, 2019 at 10:59

5 Answers 5

8

There is a Status code in your Result.

responseTask.Result.StatusCode

Or even better

var response = await client.SendAsync(request);
var statusCode = response.StatusCode;
Sign up to request clarification or add additional context in comments.

6 Comments

Will the above not simply return with the response OK if successful? Isn't OP also asking for the code number?
This will return the status code. Ok is 200, if it is something else, it will be that value.
Yeah, to return the statuscode value you would need to do (int)response.StatusCode
There are multiple enums for status code. learn.microsoft.com/en-us/dotnet/api/… You can compare with it.
The continue with, returns a Task not a response value so the var needs to be changed to HttpResponseMessage response = await .... I would suggest that you remove the continueWith as it is not needed at all, and proceed with the code I shared with you above (withou the continueWith).
|
3
  • It helps to avoid using ContinueWith if you're already inside an async function because you can use the (much cleaner) await keyword.

  • If you await the SendAsync call you'll get a HttpResponseMessage object you can get the status code from:

  • Also, wrap your IDisposable objects in using() blocks (except HttpClient - which should be a static singleton or better yet, use IHttpClientFactory).

  • Don't use HttpClient.DefaultRequestHeaders for request-specific headers, use HttpRequestMessage.Headers instead.

  • The Connection: Keep-alive header will be sent by HttpClientHandler automatically for you.
  • Are you sure you need to send Cache-control: no-cache in the request? If you're using HTTPS then it's almost guaranteed that there won't be any proxy-caches causing any issues - and HttpClient does not use the Windows Internet Cache either.
  • Don't use Encoding.UTF8 because it adds a leading byte-order-mark. Use a private UTF8Encoding instance instead.
  • Always use .ConfigureAwait(false) with every await on code that does not run in a thread-sensitive context (such as WinForms and WPF).
private static readonly HttpClient _httpClient = new HttpClient();
private static readonly UTF8Encoding _utf8 = new UTF8Encoding( encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true );

static async Task CreateConsentAsync( Uri uri, ConsentHeaders cconsentHeaders, ConsentBody cconsent )
{
    using( HttpRequestMessage req = new HttpRequestMessage( HttpMethod.Post, uri ) )
    {
        req.Headers.Accept.Add( new MediaTypeWithQualityHeaderValue("*/*") );
        req.Headers.Add("Cache-Control", "no-cache");
        req.Headers.Add("otherHeader", myValue);
        //etc. more headers added, as needed...

        String jsonObject = JsonConvert.SerializeObject( cconsent, Formatting.Indented );
        request.Content = new StringContent( jsonObject, _utf8, "application/json");

        using( HttpResponseMessage response = await _httpClient.SendAsync( request ).ConfigureAwait(false) )
        {
            Int32 responseHttpStatusCode = (Int32)response.StatusCode;
            Console.WriteLine( "Got response: HTTP status: {0} ({1})", response.StatusCode, responseHttpStatusCode );
        }
    }
}

3 Comments

thank you very much for your response (pun not intended :-) - how could I "get a HttpResponseMessage object" and read the number (i.e. 200 or 201 etc) - could you post a snipet please? Also important: how may I avoid the ContinueWith in the above code? THANK you in advance!
Thank you very much, as a matter of fact is a good upgrade on my code. However, the ConsoleWriteLine("Got response... returns a string ("Created" in my case, depends on the rest API of course - but not the HTTP code, I was expecting int, i.e. 200, 201 etc)
@Nick To get the Int32/int status code, cast the StatusCode property. I've updated my answer.
1

You could simply check the StatusCode property of the response:

https://learn.microsoft.com/en-us/previous-versions/visualstudio/hh159080(v=vs.118)?redirectedfrom=MSDN

static async void dotest(string url)
{
    using (HttpClient client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync(url);

        if (response.IsSuccessStatusCode)
        {
            Console.WriteLine(response.StatusCode.ToString());
        }
        else
        {
            // problems handling here
            Console.WriteLine(
                "Error occurred, the status code is: {0}", 
                response.StatusCode
            );
        }
    }
}

1 Comment

The response object should be wrapped in a using block. Also, HttpClient objects should not be short-life'd (so don't dispose of the HttpClient immediately).
0

@AthanasiosKataras is correct for returning the status code itself but if you would also like to return the status code value (ie 200, 404). You can do the following:

var response = await client.SendAsync(request);
int statusCode = (int)response.StatusCode

The above will give you the int 200.

EDIT:

Is there no reason why you cannot do the following?

using (HttpResponseMessage response = await client.SendAsync(request))
{
    // code
    int code = (int)response.StatusCode;
}

7 Comments

this seems soooo close!! How may I modified my statement? await client.SendAsync(request).ContinueWith(responseTask => { Console.WriteLine("RESPONSE: {0}", responseTask.Result.StatusCode); }); When I use this, I get a string, i.e. "Created" etc. but when I use responseTask.Result.StatusCode.GetTypeCode(); I receive Int32 !!! Where is this 200 or 201 number....?
@Nick (int)responseTask.Result.StatusCode
As per previous comment: extremely useful tip. I do var response await client.SendAsync(request).ContinueWith(responseTask => {Console.WriteLine("RESPONSE: {0}", responseTask.Result.... and then "int statusCode = (int)response.StatusCode;" but I get an error message on the first statement (the var response await...) : Implicitly typed variables must be initialized. What am I missing please?...
@Nick If you stop it on response, does it have a value?
you mean at var response = await client... etc.. ? It throws error there unfortunately, and I desperately want to debug it.. Says "Implicitly-typed variables must be initialized" but i don't know as what to initialize it..
|
0

What happened to me is that I forgot to change the as statement to the correct type. For example:

// Controller side - sending 202
return StatusCode((int)HttpStatusCode.Accepted, new GenericResultResponse<string>()
{
    Data,
    Message,
    Success = true
});

// test side - trying to convert to OkObjectResult
var response = await _controller.myAction(It.IsAny<Request>()) as OkObjectResult;

Corrected test

// test side
var response = await _controller.myAction(It.IsAny<Request>()) as ObjectResult;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.