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
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
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
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.
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; }
}
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);
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>
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" }
});
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
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.
GetString
, PostJSONForString
or PostXMLForString
. After confirmation you can then use the methods with instant deserialization.HttpConfiguration.RelaxSslCertValidation
= true
.