Here is an example of how to do REST web requests in C#. The example shown is POST but for GET just remove the request body stuff and change the request.Method:
updated with checks for Basic Auth and GET requests
// Create a request and set the headers HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.Method = "POST" request.ContentType = contentType request.UserAgent = userAgent request.Timeout = timeout if (useBasicAuth == true) { // Create a token for basic authentication and add a header for it String authorization = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(username + ":" + password)); request.Headers.Add("Authorization", "Basic " + authorization) } if (request.Method == "POST" && requestBody != null) { // Convert the request contents to a byte array and include it byte[] requestBodyBytes = System.Text.Encoding.UTF8.GetBytes(requestBody); Stream requestStream = request.GetRequestStream(); requestStream.Write(requestBodyBytes, 0, requestBodyBytes.Length); requestStream.Close(); } // Initialize the response HttpWebResponse response = null; String responseText = null; // Now try to send the request try { response = request.GetResponse() as HttpWebResponse; // expect the unexpected // WebException may be thrown already for some of this already // like timeout or 404 if (request.HaveResponse == true && response == null) { String msg = "response was not returned or is null"; throw new WebException(msg); } if (response.StatusCode != HttpStatusCode.OK) { String msg = "response with status: " + response.StatusCode + " " + response.StatusDescription; throw new WebException(msg); } // check response headers for the content type contentType = response.GetResponseHeader("Content-Type"); // get the response content StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8); responseText = reader.ReadToEnd(); reader.Close(); // handle failures } catch (WebException e) { if (e.Response != null) { response = (HttpWebResponse) e.Response; log.Error(response.StatusCode + " " + response.StatusDescription); } else { log.Error(e.Message); } // and clean up after ourselves } finally { if (response != null) { response.Close(); } } // display the response if (responseText != null) { System.Console.Write(responseText); }
As you can see, there’s a lot of drudgework here — and this is an abbreviated example. Ideally, I’d like to wrap it all up in a class with a pretty bow so I can do something like this:
RestClient client = new RestClient(); System.Console.Write(client.get(url));
Of course a more complex example might look more like this:
var settings = new Dictionary<String, String> { {"key1", "value1"}, {"key2", "value2"} }; RestClient client = new RestClient(settings); client.Url = "http://rest.example.com/1/resource/method?param=value" client.BasicAuth("username", "password"); client.Headers.Add("header", "value"); client.post("content") System.Console.WriteLine(client.Response.Body); foreach (KeyValuePair<String, String> header in client.Response.Headers) { System.Console.WriteLine(header.Key ": " + header.Value); } if (client.Response.Error) { System.Console.WriteLine(client.Response.StatusCode) System.Console.WriteLine(client.Response.Error.Message) }
Then I could simply extend RestClient to handle things like urls, parameters, and custom headers for each webservice client class.
Currently, I’m sorry to admit I have a jumble of cut & paste code that intermingles JSON serialization with HttpWebRequest handling — but at least I’ve abstracted out URLs & stream handling into a base class.
For maintainability (by someone else) I’ve avoided extending HttpWebRequest and HttpWebResponse to make them less painful. Also, by not allowing default constructors, I’d have to end up using composition.
I’ve looked at other libraries, like Hammock, but I don’t really see much value added. The level of abstraction it uses for just the 2 lines of basic auth code is staggering.