Search code examples
c#httprequest

How to I get the HTTP Status Code from a http request


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

Solution

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