Computers And Industry

HttpClient Sample In C#


The following example shows how to use the HttpClient in C#. This sample simply makes a call out to google.com and displays the return html in the console window. This sample uses a wrapper class around the HttpClient object in order to provide error checking, additional features, call backs, etc. Note that this class can be used in any project type (ie Net, AspNetCore, etc.) Note too that this is a real world production class so...

Using the Class


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;

namespace Samples
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "WebClient Sample";
            Console.WriteLine(Console.Title);
            Console.WriteLine();
            Console.WriteLine("***BEGIN SAMPLE OUTPUT***");

            // define the new wrapper class
            PFSHttp h = new PFSHttp();

            // set the target url
            h.Url = "http://www.google.com";

            // perform a Get
            HttpStatusCode c1 = h.Get().Result;

            // get the response as a string
            string s = h.GetResponseAsString().Result;

            // write the string to the console window
            Console.WriteLine(s);

            // dispose of the wrapper class.
            h.Dispose();

            Console.WriteLine("***END SAMPLE OUTPUT***");
            Console.ReadKey();
        }
    }
}  // END PROGRAM



The PFSHttp Wrapper for the HttpClient Class


#pragma warning disable IDE1005
#pragma warning disable IDE0032

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Net.Http.Headers;
using System.Xml;
using System.Net.Mime;
using System.Diagnostics;


namespace Samples
{

    public class PFSHttp: IDisposable
    {
        // header constants
        private const string HEADER_CONTENT_LENGTH = "Content-Length";
        private const string HEADER_CONTENT_TYPE = "Content-Type";

        // defaults for timeouts
        private const int DEFAULT_TIMEOUT_HOURS = 0;
        private const int DEFAULT_TIMEOUT_MINUTES = 2;
        private const int DEFAULT_TIMEOUT_SECONDS = 0;

        // response handler delegates.
        public delegate void HttpClientResponseHandler(PFSHttp objThis, object UserDataObject);
        public delegate void HttpClientTimeoutHandler(PFSHttp objThis, object UserDataObject);
        public delegate void HttpClientErrorHandler(PFSHttp objThis, object UserDataObject);

        // Headers 
        private List> lstHeaders = new List>();                 // list that holds headers
        private List> lstAcceptHeaders = new List>();         // accept headers
        private List> lstQueryParameters = new List>();         // This holds 

        // local handlers (functions)
        private HttpClientResponseHandler dlgResponseHandler = null;
        private HttpClientTimeoutHandler dlgTimeoutHandler = null;
        private HttpClientErrorHandler dlgErrorHandler = null;

        // request object
        private HttpClient objHttpClient = null;

        // response object
        private HttpResponseMessage objHttpResponse = null;


        // User Data that is state persistent
        private object objUserData = new object();

        // local class properties.
        private string strUrl = "";                                                                          
        private string strUserID = "";
        private string strPassword = "";
        private int intTimeoutHours = DEFAULT_TIMEOUT_HOURS;
        private int intTimeoutMinutes = DEFAULT_TIMEOUT_MINUTES;
        private int intTimeoutSeconds = DEFAULT_TIMEOUT_SECONDS;
        private string strID = "";

        private int intExceptionCode = 0;
        private string strExceptionSource = "";
        private string strExceptionMessage = "";
        private bool boolExceptionFlag = false;


        // timespan variable
        private TimeSpan tsHttpTimeOut = new TimeSpan(DEFAULT_TIMEOUT_HOURS, DEFAULT_TIMEOUT_MINUTES, DEFAULT_TIMEOUT_SECONDS);

        // post bodys.
        private string strPostBody = "";
        private string strXml = "";
        private string strJson = "";


        // Get the HttpClient object
        public HttpClient HttpRequest
        {
            get { return objHttpClient; }
        }

        // Get the Response Message object
        public HttpResponseMessage HttpResponse
        {
            get { return objHttpResponse; }
        }

        // Get the Status Code
        public HttpStatusCode StatusCode
        {
            get {
                    HttpStatusCode rt = HttpStatusCode.BadRequest;
                    if (objHttpResponse != null)
                    {
                        rt = objHttpResponse.StatusCode;  
                    }

                    return rt;
                }
        }

        // Get the exception code.
        public int ExceptionCode
        {
            get { return intExceptionCode; }
        }

        // the exception source
        public string ExceptionSource
        {
            get { return strExceptionSource; }
        }

        // the exception message
        public string ExceptionMessage
        {
            get { return strExceptionMessage; }
        }

        // flag indicating whether exception occured
        public bool ExceptionFlag
        {
            get { return boolExceptionFlag; }
        }

        // stateful user data that will get 
        public object UserData
        {
            get { return objUserData; }
            set { objUserData = value; }

        }

        // url.  May or may not contain query parameters
        public string Url
        {
            get { return strUrl; }
            set { strUrl = value; }
        }

        // a string value user defined.
        public string ID
        {
            get { return strID; }
            set { strID = value; }
        }

        // function after response received.
        public HttpClientResponseHandler ResponseHandler
        {
            get { return dlgResponseHandler; }
            set { dlgResponseHandler = value; }
        }

        // function called if timeout occurs
        public HttpClientTimeoutHandler TimeoutHandler
        {
            get { return dlgTimeoutHandler; }
            set { dlgTimeoutHandler = value; }
        }

        // function called if error occurs
        public HttpClientErrorHandler ErrorHandler
        {
            get { return dlgErrorHandler; }
            set { dlgErrorHandler = value; }
        }

 

        // post body.  manually set
        public string PostBody
        {
            get { return strPostBody; }
            set { strPostBody = value; }
        }

        // used for submitting xml only
        public string Xml
        {
            get { return strXml; }
            set { strXml = value; }
        }

        // used for submitting JSON
        public string Json
        {
            get { return strJson; }
            set { strJson = value; }
        }

 
        // user id
        public string UserID
        {
            get { return strUserID; }
            set { strUserID = value; }
        }

        // user password
        public string Password
        {
            get { return strPassword; }
            set { strPassword = value; }
        }

        // timeout hours
        public int TimeoutHours
        {
            get { return intTimeoutHours; }
            set { intTimeoutHours = value; }
        }

        // timeout minutes
        public int TimeoutMinutes
        {
            get { return intTimeoutMinutes; }
            set { intTimeoutMinutes = value; }
        }

        // timeout seconds
        public int TimeoutSeconds
        {
            get { return intTimeoutSeconds; }
            set { intTimeoutSeconds = value; }
        }
        

        // -------------------------------------------
        // Adds a query or post parameter
        // -------------------------------------------
        public void AddQueryParameter(string sKey, string sValue)
        {
            KeyValuePair kvp = new KeyValuePair(sKey, sValue);
            lstQueryParameters.Add(kvp);
        }

        // adds string query or post parameter
        public void aqp(string sKey, string sValue)
        {
            AddQueryParameter(sKey, sValue);
        }

        // adds datetime query or post parameter
        public void aqp(string sKey, DateTime dtValue)
        {
            string strDt = dtValue.ToString("yyyy-MM-ddTHH:mm:ss");
            AddQueryParameter(sKey, strDt);
        }

        // adds int query or post parameter
        public void aqp(string sKey, int nValue)
        {
            AddQueryParameter(sKey, nValue.ToString());
        }

        // adds double query or post parameter
        public void aqp(string sKey, double dValue)
        {
            AddQueryParameter(sKey, dValue.ToString());
        }

        // adds long query or post parameter
        public void aqp(string sKey, long lValue)
        {
            AddQueryParameter(sKey, lValue.ToString());
        }

        // adds float query or post parameter
        public void aqp(string sKey, float fVal)
        {
            AddQueryParameter(sKey, fVal.ToString());
        }

        // adds decimal query or post parameter
        public void aqp(string sKey, decimal dValue)
        {
            AddQueryParameter(sKey, dValue.ToString());
        }

        // adds byte query or post parameter
        public void aqp(string sKey, byte b)
        {
            aqp(sKey, (int)b);
        }

        // adds char query or post parameter
        public void aqp(string sKey, char c)
        {
            AddQueryParameter(sKey, c.ToString());
        }

        // adds boolean query or post parameter
        public void aqp(string sKey, bool b)
        {
            int nval = 0;
            if (b)
            {
                nval = 1;
            }
            aqp(sKey, nval);
        }

        // ----------------------------------------------
        // Adds a request header
        // ----------------------------------------------
        public void AddHdr(string sKey, string sVal)
        {
            // only add 
            if (string.Compare(sKey.ToLower(), HEADER_CONTENT_LENGTH.ToLower()) != 0)
            {

                KeyValuePair kvp = new KeyValuePair(sKey, sVal);
                lstHeaders.Add(kvp);
            }
        }

        // -----------------------------------------
        // Adds an accept header
        // -----------------------------------------
        public void AddAcceptHdr(string sKey)
        {
            KeyValuePair kvp = new KeyValuePair(sKey, "");
        }

        public void AddAcceptHdr(string sKey, double dVal)
        {
            KeyValuePair kvp = new KeyValuePair(sKey, dVal.ToString());
        }

       
        // ------------------------------------------------------------
        // Gets the response as a string
        // ------------------------------------------------------------
        public async Task GetResponseAsString()
        {
            string s = "";

            if (objHttpResponse != null)
            {
                if (objHttpResponse.Content != null)
                {
                    s = await objHttpResponse.Content.ReadAsStringAsync();
                }
            }
            return s;
        }

        // ------------------------------------------------------------
        // Gets response as a text reader
        // ------------------------------------------------------------
        public async Task GetResponseAsTextReader()
        {

            TextReader tx = null;

            try
            {
                string s = await GetResponseAsString();
                tx = new StringReader(s);
            }
            catch (Exception) { }

            return tx;
        }


        // ------------------------------------------------------------
        // Gets response as a xml reader
        // ------------------------------------------------------------

        public async Task GetResponseAsXmlReader()
        {
            XmlReader xr = null;

            try
            {
                TextReader tx = await GetResponseAsTextReader();
                xr = XmlReader.Create(tx);
            }
            catch (Exception) { }

            return xr;

        }

        // ---------------------------------------------------------
        // Gets response as a stream
        // ---------------------------------------------------------
        public async Task GetResponseAsStream()
        {
            Stream fs = null;

            if (objHttpResponse != null)
            {
                if (objHttpResponse.Content != null)
                {
                    try
                    {
                        Stream fss = await objHttpResponse.Content.ReadAsStreamAsync();
                        fs = fss;
                    }
                    catch (Exception) { }
                }
            }
            return fs;
        }


        // -----------------------------------------------------------
        // Gets response as a byte array
        // -----------------------------------------------------------
        public async Task GetResponseAsByteArray()
        {
            byte[] b = null;

            if (objHttpResponse != null)
            {
                if (objHttpResponse.Content != null)
                {
                    try
                    {
                        b = await objHttpResponse.Content.ReadAsByteArrayAsync();
                    }
                    catch (Exception)
                    { }
                }
            }
            return b;
        }



        // --------------------------------------------------------------
        // Does a get call.
        // --------------------------------------------------------------
        public async Task Get()
        {
            HttpStatusCode rc = HttpStatusCode.BadRequest;

            objHttpResponse = new HttpResponseMessage();

            // defines a new http client
            SetNewHttpClient();


            // now build the url.  
            string sUrl = strUrl;


            if (lstQueryParameters.Count > 0)
            {
                string sep = "";
                sUrl = sUrl + "?";
                for (int i = 0; i < lstQueryParameters.Count; i++)
                {
                    string tmp = sep + lstQueryParameters[i].Key + "=" + WebUtility.UrlEncode(lstQueryParameters[i].Value);
                    sUrl += tmp;
                    sep = "&";
                }
            }


            // add the headers
            AddHeaders();

            // do the get request
            try
            {
               

                // wait the whole time
                objHttpResponse = await objHttpClient.GetAsync(sUrl, HttpCompletionOption.ResponseContentRead);

                // capture the status code
                rc = objHttpResponse.StatusCode;




                // if the response is a timeout, then if the handler is defined, do the timeout handler, otherwise 
                // try and do the regular response handler
                if (rc == HttpStatusCode.RequestTimeout || rc == HttpStatusCode.GatewayTimeout)
                {
                    if (dlgTimeoutHandler != null)
                    {
                        dlgTimeoutHandler(this, objUserData);
                    }
                    else if (dlgResponseHandler != null)
                    {
                        dlgResponseHandler(this, objUserData);
                    }

                }

                // if not a timeout handler, then if the response handler is defined, 
                // do that.
                else
                {
                    if (dlgResponseHandler != null)
                    {
                        dlgResponseHandler(this, objUserData);
                    }
                }


            }

            // exception occurred
            catch (Exception ex)
            {
                boolExceptionFlag = true;
                intExceptionCode = ex.HResult;
                strExceptionSource = ex.Source;
                strExceptionMessage = ex.Message;

                if (dlgErrorHandler != null) 
                {
                    dlgErrorHandler(this, objUserData);
                }
                else if (dlgResponseHandler != null)
                {
                    dlgResponseHandler(this, objUserData);
                }

            }

            return rc;
        }




        // -----------------------------------------------
        // does a post call
        // -----------------------------------------------
        public async Task Post()
        {
            HttpStatusCode rc = HttpStatusCode.BadRequest;

            int nContentLength = 0;

            // this is the post content
            HttpContent uCont;


            // defines a new http client
            SetNewHttpClient();



            // now we need to either post the query parameters, the preset post data, or the xml.
            if (strXml.Length == 0)
            {
                if (strJson.Length == 0)
                {

                    // if the post body is blank, then try and set via 
                    // any query parameters.
                    if (PostBody.Length == 0)
                    {
                        string sep = "";
                        for (int i = 0; i < lstQueryParameters.Count; i++)
                        {
                            KeyValuePair kvp = lstQueryParameters[i];
                            strPostBody += sep + kvp.Key + "=" + WebUtility.UrlEncode(kvp.Value);
                            sep = "&";
                        }
                        uCont = new StringContent(strPostBody);

                    }

                    else
                    {
                        uCont = new StringContent(strPostBody);
                    }

                    nContentLength = strPostBody.Length;
                }

                else
                {
                    nContentLength = strJson.Length;
                    uCont = new StringContent(strJson);
                }

            }
   
            else
            {
                nContentLength = strXml.Length;
                uCont = new StringContent(strXml);
            }

            // always add the content length
            objHttpClient.DefaultRequestHeaders.Add(HEADER_CONTENT_LENGTH, nContentLength.ToString());

            // add the rest of the headers
            AddHeaders();


            // get the response.
            try
            {
 
                // post the content.  wait for response
                objHttpResponse = await objHttpClient.PostAsync(Url, uCont);

      
                // get the status code
                rc = objHttpResponse.StatusCode;



                // if the response is a timeout, then if the handler is defined, do the timeout handler, otherwise 
                // try and do the regular response handler
                if (rc == HttpStatusCode.RequestTimeout || rc == HttpStatusCode.GatewayTimeout)
                {
                    if (dlgTimeoutHandler != null)
                    {
                        dlgTimeoutHandler(this, objUserData);
                    }
                    else if (dlgResponseHandler != null)
                    {
                        dlgResponseHandler(this, objUserData);
                    }

                }

                // if not a timeout handler, then if the response handler is defined, 
                // do that.
                else
                {
                    if (dlgResponseHandler != null)
                    {
                        dlgResponseHandler(this, objUserData);
                    }
                }


            }

            // exception occured. 
            catch(Exception ex)
            {

                boolExceptionFlag = true;
                intExceptionCode = ex.HResult;
                strExceptionSource = ex.Source;
                strExceptionMessage = ex.Message;

                if (dlgErrorHandler != null)
                {
                    dlgErrorHandler(this, objUserData);
                }
                else if (dlgResponseHandler != null)
                {
                    dlgResponseHandler(this, objUserData);
                }
            }
  
            return rc;
        }


        // -----------------------------------------------------------
        // Sets a new HttpClient
        // -----------------------------------------------------------
        private void SetNewHttpClient()
        {
            // if the user id is specified, then we 
            // need to specify a user id and passsword
            if (strUserID.Length > 0)
            {
                HttpClientHandler cliHandler = new HttpClientHandler();
                cliHandler.Credentials = new NetworkCredential(strUserID, strPassword);
                objHttpClient = new HttpClient(cliHandler);
            }
            else
            {
                objHttpClient = new HttpClient();
            }

            // set the client timeout
            objHttpClient.Timeout = new TimeSpan(intTimeoutHours, intTimeoutMinutes, intTimeoutSeconds);

        }




        // --------------------------------------------------------
        // This adds the request and accept headers to the client
        // --------------------------------------------------------
        private void AddHeaders()
        {
            // add the headers except for content type and content length
            for (int i = 0; i < lstHeaders.Count; i++)
            {
                KeyValuePair kvp = lstHeaders[i];
                objHttpClient.DefaultRequestHeaders.Add(kvp.Key, kvp.Value);
            }

            // add the accept headers
            for (int i = 0; i < lstAcceptHeaders.Count; i++)
            {
                MediaTypeWithQualityHeaderValue mtyp = null;
                KeyValuePair kvp = lstAcceptHeaders[i];
                if (kvp.Value.Length > 0)
                {
                    mtyp = new MediaTypeWithQualityHeaderValue(kvp.Key, Convert.ToDouble(kvp.Value));
                }
                else
                {
                    mtyp = new MediaTypeWithQualityHeaderValue(kvp.Key);
                }
                objHttpClient.DefaultRequestHeaders.Accept.Add(mtyp);
            }
        }

        // ----------------------------------------------------
        // Dispose of everything
        // ----------------------------------------------------
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                objHttpResponse.Dispose();
                objHttpClient.Dispose();
                dlgResponseHandler = null;
                dlgErrorHandler = null;
                dlgTimeoutHandler = null;
                objUserData = null;
            }
        }

        // -----------------------------------------------------
        // Disposing
        // -----------------------------------------------------

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }






        // ----------------------------------------------------------------
        // Convenience Routines
        // ----------------------------------------------------------------

        // form submit.
        public void AddDefaultPostHeaders()
        {
            AddHdr(HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded");
        }

    
        // convenience for xml posts
        public void AddDefaultXmlPostHeaders()
        {
            AddHdr(HEADER_CONTENT_TYPE, "text/xml");
        }

        // convenience for json post
        public void AddDefaultJsonPostHeader()
        {
            AddHdr(HEADER_CONTENT_TYPE, "application/json");
        }

        // convenience for xml accept
        public void AddXmlAcceptHeader()
        {
            AddAcceptHdr("text/xml");
        }

        // convenience for JSON accept
        public void AddJsonAcceptHeader()
        {
            AddAcceptHdr("application/json");
        }

 

    }
}     // END PfsHttp CLASS




Open Source

Paul F. Sirpenski
Personal Open Source Directory Of Paul F. Sirpenski

ASP.NET Core
Open Source directory Of the Microsoft Asp.Net Core project.

Developed By Paul F. Sirpenski. Copyright 2021.