Rext Documentation

A simple smart HttpClient wrapper library for dotnet. Just plug and play.
Safely handles request with JSON, XML and Form Data

A project by Prince Tegaton

Installation

RextHttpClient is built for (dotnet) NetStandard projects only and is NOT compatible with NetFramework. It is available via nuget for Visual Studio. You can install from the CLI with the below command.

Install-Package RextHttpClient

Basic Usage

All basic API operations have been made available for quick access via IRextHttpClient. If you wish to make a direct call and handle deserialization yourself, then call _rext.MakeRequest method.


IRextHttpClient _rext = new RextHttpClient(); // create new instance via new or DI
                    

Make http call with result deserialized to object.


string url = "http://myapp.com/api/employee/getemployee";
var rsp = await _rext.GetJSON<@Person>(url); // download json
var rsp = await _rext.GetXML<@Person>(url); // download xml
var rsp = await _rext.GetString(url); // download string

Console.WriteLine($"{rsp.StatusCode} - {rsp.Message} - 
Duration: {_rext.Stopwatch?.ElapsedMilliseconds}ms"); // get duration of http call
Console.WriteLine(rsp?.Data); // get deserialized result as object
                    

All Rext methods for http call have overloads for adding more options to suit your need. You supply a type of T and the result from the call is deserialized into it. To retrieve the result you have to check if the call was successful with _rext.IsSuccess, if the value is true then access the data with _rext.Data.

Note: Only successful response (200) are deserialized by default. to allow deserialization for all response types, set RextOptions.DeserializeSuccessResponseOnly = false or from the global configuration section

Handling Payloads

How does Rext handle payload?

Simple! for GET requests, all object (payloads) are converted to querystring. POST requests are converted to JSON, XML or Form depending on the chosen method.

The response object from Rext after a call is as seen below:

IsSuccess : This is true if the http repsonse code is 200
StatusCode : The Http StatusCode associated with the call response
Content : Plain string response from the http call
Message : Rext message on the status of the request and also shows handled exception messages
Data : Generic type of T for response to be deserialized

Note: Ignore the '@' in <@Object> shown in the code snippets.

Add other parameters

var rsp = await _rext.GetJSON<@IEnumerable<@Person>>("http://myapp.com/api/people/getpeople",
                        new { location = "Lagos" }, // object get converted to querystring for GET
                        new { header1 = "value1" });
                    

Change the request content-type if needed by exploring the overload with RextOption


var rsp = await _rext.PostJSON<@Employee>(new RextOptions
                    {
                        Url = "http://myapp.com/api/employee/getemployee",
                        ContentType = "application/xml",
                        Header = new { header2 = "value2" },
                        Payload = new Employee { id = 1002, Name = "Francisca" }
                    });
                    

Handling XML payloads and response requires the elements and model properties to match as usual. Arrays requires you to set the element name in most cases. Here is an example


[XmlRoot(ElementName = "ArrayOfPerson")] // match root node name <@ArrayOfperson>...<@ /ArrayOfPerson>
public class ArrayOfPerson
{
    [XmlElement(ElementName = "Person")]
    public List Person { get; set; }
}

[XmlRoot(ElementName = "Person")]
public class Person
{
    [XmlElement(ElementName = "Name")]
    public string Name { get; set; }

    [XmlElement(ElementName = "Location")]
    public string Location { get; set; }
}

Posting Form Data

Rext make it easy to submit form data to APIs. You just feed the object to the method. By default Rext uses multipart/form-data content-type when submitting content. You can change it to application/x-www-form-urlencoded by setting isUrlEncoded=true


var person = new Person
{
    Name = "Prince Tegaton",
    Location = "Lagos, Nigeria",
    Status = true
};

var rsp = await _rext.PostForm(url, person, isUrlEncoded : true);
                            

Other HTTP Actions

DELETE: Rext provide overloads for http delete actions which are Delete and DeleteJSON<@T>

PUT: Rext also provide overloads for http update (PUT) actions which are PutJSON<@T> and PutJSONForString<@T>

Using the Header Extension

You can explore the Rext flexible Header Extension when making calls


var headers = new Dictionary<@string, string>
{
    { "header1", "value 1" },
    { "header2", "value 2" }
};

var rsp = _rext.AddHeader(headers)
                .AddHeader("header3", "value 3")
                .UseBearerAuthentication("ueyuywyt.iduizcg0e.kiuwnk==")
                .UseBasicAuthentication("api_username", "api_passkey")
                .PostJSON<@Person>(new RextOptions
                {
                    Url = "http://myapp.com/api/employee/getemployee",
                    ContentType = "application/xml",
                    Header = new { header4 = "value4" }
                });
                                                

Global Configuration

You can setup app wide configuration with various options for once. Some can be overriden on specific calls too.


static void Main(string[] args)
{
    RextHttpClient.Setup(opt =>
    {
        opt.HttpConfiguration = new RextHttpCongifuration
        {
            BaseUrl = "http://myapp.com/api",
            ProxyAddress = "http://127.0.0.1:80",
            ThrowExceptionOnDeserializationFailure = false,
            ThrowExceptionIfNotSuccessResponse = true,
            DeserializeSuccessResponseOnly = true
            //Timeout = 60
        };
        opt.SuppressRextExceptions = false;
        opt.BeforeCall = delegate ()
        {
            Console.WriteLine("---About to initiate http task");
        };
        opt.AfterCall = delegate ()
        {
            Console.WriteLine("---End of http task");
        };
        opt.OnError = delegate ()
        {
            Console.WriteLine("---Error occured");
        };
        opt.OnStatusCode = (int code) => ErrorCodeHandler();
        opt.StatusCodesToHandle = new int[] { 401, 500 };
    });

    IRextHttpClient _rext = new RextHttpClient();
}

static void ErrorCodeHandler(int code)
{
    if (code == 401)
        Console.WriteLine($"---handling Unauthorized Error");
    if (code == 500)
        Console.WriteLine($"---handling Internal Server Error");
}

RextHttpCongifuration contains

HttpConfiguration.BaseUrl : Set the base url for every http call
HttpConfiguration.ProxyAddress : Set a proxy address when behind a corporate network eg: http://127.0.0.1:80. Mostly valid for development mode. Value should be passed from a dynamic setting
HttpConfiguration.Header : Set a default header for every http call via IDictionary(string, string) IList(string, string) or key-value object (new { Authorization = "xxxx" }
HttpConfiguration.RelaxSslCertValidation : If set to true, httpclient will be configured to ignore SSL validations. This is useful when using selfsigned certificates
HttpConfiguration.ThrowExceptionIfNotSuccessResponse : If set to true, an exception is thrown whenever httpclient returns a statuscode other than 200
HttpConfiguration.ThrowExceptionOnDeserializationFailure : If set to true, an exception is thrown whenever a response deserialization fails
HttpConfiguration.DeserializeSuccessResponseOnly : If set to true, generic response will be deserialized only when status code is 200*. Default value is true
HttpConfiguration.Timeout : Http timeout in seconds HttpConfiguration.Certificate : Configure X509Certificate Server certificate information
HttpConfiguration.HttpCompletionOption : Set the global HttpClient HttpCompletionOption call for every call. ResponseContentRead | ResponseHeaderRead

Other properties of Rext global configuration are:

HttpClient : Create a custom client for usage. This will discard every setting in RextHttpCongifuration.HttpConfiguration
SuppressRextExceptions : This allow you to retrieve exception messages in RextHttpClient.Message. Set to false if you want to handle all exceptions from your code
BeforeCall : Execute action before any http call
AfterCall : Execute action after any http call
OnError : Execute action when an exception is thrown by RextHttpClient
OnStatusCode : Execute action for a specific statuscode
StatusCodesToHandle : Array for all statuscodes to run custom action for
EnableStopwatch : Determine if Rext Stopwatch should be used. Value is True by default

Using Server Certificate

Rext allow you to attach a Certificate[.pfx] file when making calls to secure services that requires such.

Fetch certificate file from folder


RextHttpClient.Setup(opt =>
{
    opt.HttpConfiguration.Certificate = new CertificateInfo
    {
        FilePath = "server_appstore.pfx",
        Password = "12345" // if cert have a password
    };
});
                        

Read certificate file content as bytes


byte[] cert_bytes = System.IO.File.ReadAllBytes("server_appstore.pfx");
RextHttpClient.Setup(opt =>
{
    opt.HttpConfiguration.Certificate = new CertificateInfo
    {
        CertificateBytes = cert_bytes
        Password = "12345" // if cert have a password
    };
});
                            

If you specify both a FilePath and CertificateBytes, Rext will use the file only.

Troubleshooting Tips

  • Deserialization Failure: Simply download the response as string to analyse the incoming fields if they matches the model you want to deserialize it to. You can use GetString, PostJSONForString or PostXMLForString. After confirmation you can then use the methods with instant deserialization.
  • The SSL Connection could not be established: This is because the API server certificate on https is not valid. To bypass this validation, set HttpConfiguration.RelaxSslCertValidation = true.