Created
January 2, 2013 09:54
-
-
Save dhlavaty/4433398 to your computer and use it in GitHub Desktop.
Simplest method to do a REST API calls in c# with basic .NET classes (no external library needed). I use it when communicationg with Recurly.com REST services.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Simplest method to do a REST API calls in c# with basic .NET classes. | |
I use it when communicationg with Recurly.com REST services. | |
*/ | |
using System; | |
using System.Collections.Generic; | |
using System.Data; | |
using System.IO; | |
using System.Linq; | |
using System.Security.Cryptography; | |
using System.Text; | |
using System.Transactions; | |
using System.Web.Mvc; | |
using System.Xml; | |
/// <summary> | |
/// Helping class, that solves problem that Microsoft has done. See remarks. | |
/// </summary> | |
/// <remarks> | |
/// 1. When you use <see cref="System.Net.WebClient"/>, you cannot get response status (200 - OK, 404 - Not Found, ...) | |
/// | |
/// 2. When you use <see cref="System.Net.WebRequest"/>, you cannot change HTTP headers before sending request | |
/// | |
/// 3. Use <see cref="System.Net.HttpWebRequest"/> directly is not possible. | |
/// | |
/// Solution: | |
/// | |
/// Microsoft hase done a "great job" again. Most useful method <see cref="System.Net.WebClient.GetWebRequest"/> | |
/// is <c>protected</c>. So we must use this class as a hack. | |
/// </remarks> | |
public class BetterWebClient : System.Net.WebClient | |
{ | |
/// <summary> | |
/// See <see cref="System.Net.WebRequest.GetWebRequest"/> | |
/// </summary> | |
/// <param name="address">See <see cref="System.Net.WebRequest.GetWebRequest"/></param> | |
/// <returns>See <see cref="System.Net.WebRequest.GetWebRequest"/></returns> | |
public virtual System.Net.WebRequest GetWebRequestX(Uri address) | |
{ | |
return this.GetWebRequest(address); | |
} | |
} | |
public class RestApi | |
{ | |
/// <summary> | |
/// Makes a REST API call (I'm using it with Recurly.com service) | |
/// </summary> | |
/// <remarks> | |
/// It will return either a response from a REST API call. | |
/// If any error was during comunication, this method returns empty string. | |
/// </remarks> | |
/// <param name="url">URL to fetch</param> | |
/// <returns>Returns a string, representing XML of the object.</returns> | |
/// <param name="method"><see cref="System.Net.WebRequestMethods.Http"/></param> | |
public string Fetch(string url, string method = System.Net.WebRequestMethods.Http.Get, string xmlToSend = "") | |
{ | |
DateTime startedOnUtc = DateTime.UtcNow; | |
string responseData = null; | |
string responseHeaders = null; | |
int responseStatusCode = 0; | |
try { | |
BetterWebClient webClient = new BetterWebClient(); | |
webClient.Proxy = null; | |
webClient.Headers.Add(System.Net.HttpRequestHeader.Accept, "application/xml"); | |
// You can use BASIC authorization like so (you must implement your own Recurly.ApiKeyBase64String): | |
webClient.Headers.Add(System.Net.HttpRequestHeader.Authorization, "Basic " + Recurly.ApiKeyBase64String); | |
if (false == String.IsNullOrWhiteSpace(xmlToSend)) | |
{ | |
webClient.Headers.Add(System.Net.HttpRequestHeader.ContentType, "application/xml; charset=utf-8"); | |
} | |
var webRequest = webClient.GetWebRequestX(new Uri(url)); | |
webRequest.Method = method; | |
if (false == String.IsNullOrWhiteSpace(xmlToSend)) | |
{ | |
using (StreamWriter writer = new StreamWriter(webRequest.GetRequestStream(), Encoding.UTF8)) | |
{ | |
writer.WriteLine(xmlToSend); | |
} | |
} | |
else | |
{ | |
if (method == System.Net.WebRequestMethods.Http.Put) | |
{ | |
webRequest.ContentLength = 0; // ContentLength == 0 is required for PUT requests | |
} | |
} | |
using (System.Net.WebResponse response = webRequest.GetResponse()) | |
{ | |
ProcessResponse(response, out responseData, out responseHeaders, out responseStatusCode); | |
} | |
} | |
catch (System.Net.WebException ex) | |
{ | |
using (ex.Response) | |
{ | |
ProcessResponse(ex.Response, out responseData, out responseHeaders, out responseStatusCode); | |
} | |
responseData = "<!-- " + ex.Message + " -->\r\n\r\n" + responseData; | |
} | |
finally | |
{ | |
/* YOU CAN (you should) LOG ALL YOUR COMMUNICATION WITH SERVER HERE like this: | |
var log = Log.CreateCommunicationLogObject(); | |
log.StartedOnUtc = startedOnUtc; | |
log.FinishedOnUtc = DateTime.UtcNow; | |
log.RequestMethod = method; | |
log.RequestData = String.IsNullOrWhiteSpace(xmlToSend) ? null : xmlToSend; | |
log.RequestUrl = url; | |
log.ResponseData = responseData; | |
log.ResponseStatusCode = responseStatusCode; | |
log.ResponseHeaders = responseHeaders; | |
Log.Save(); | |
*/ | |
} | |
if (responseStatusCode >= 200 && responseStatusCode < 300) | |
{ | |
// All 2xx HTTP statuses are OK | |
return responseData; | |
} | |
return String.Empty; | |
} | |
private static void ProcessResponse(System.Net.WebResponse response, out string recurlyResponse, out string responseHeaders, out int responseStatusCode) | |
{ | |
recurlyResponse = responseHeaders = String.Empty; | |
responseStatusCode = 0; | |
using (var responseStream = response.GetResponseStream()) | |
{ | |
using (System.IO.StreamReader sr = new System.IO.StreamReader(responseStream, Encoding.UTF8)) | |
{ | |
recurlyResponse = sr.ReadToEnd(); | |
} | |
} | |
responseHeaders = response.Headers.ToString(); | |
var httpWebResponse = response as System.Net.HttpWebResponse; | |
if (httpWebResponse != null) | |
{ | |
responseStatusCode = (int)httpWebResponse.StatusCode; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment