Handling the HttpWebRequest






4.50/5 (5 votes)
A utility class for accessing REST data sources
Introduction
Making calls to RESTful APIs can seem quite a daunting task, but once you have done it a few times, it really is not as scary as you might think.
I thought this little utility might be helpful for those first getting into making calls to such Web Services. This is my first article on CodeProject, so I thought I would keep it relatively simple and short(ish). It is an article for beginners after all! I say an article for beginners, because there are many out there, of all different skill levels, that seem to be attempting to create Facebook applications and the like and making calls to the provided APIs. Let's hope this helps a little!
Oh, and I welcome comments :)
Background
Recently, I started a new job that required making calls to RESTful APIs. I found myself often rewriting the GET and POST methods to make calls to the various APIs as each gave a different type of response. After a little refactoring, I created this little utility that handles at least getting the response first for processing in a different class.
Requirements
The project is built in VS2010, and can be run targeting either .NET 4, or .NET 3.5 with the Parallel Extensions library available from Microsoft.
Some knowledge of HTTP is required to understand the article - especially calls to GET and POST methods.
Glossary
I have provided a glossary for the many beginners who will be reading this article. The idea is that an upfront, plain-English explanation will help with the understanding of the topics to come.
- Asynchronous - While the common usage of the word 'asynchronous' is: not occurring at the same time, in development, it tends to represent the opposite (well, from the watcher's perspective). An asynchronous method call is one that executes on a different thread to the one it is called on. This results in code after the method call executing immediately after the method begins, but not necessarily before it has finished.
- Blocking - Commonly used to refer to code that prevents the User Interface from responding, but can also be code that prevents other code from executing. An example of this is the modal dialog (a
MessageBox
in .NET, or aForm
shown withShowDialog()
) which will not execute the code after it is shown - at least not until the dialog is closed. - Request - In this instance, a request represents a call to a URL with a set of parameters. A parallel in speech is when someone asks for something; the response may be what the person asked for, something unexpected, or even nothing at all. Browsers (IE, Firefox, etc.) all communicate with websites using requests.
- Response - What is received after a request. The remote web server responds to requests - this response could include the HTML for a web page, or in this case, most likely an XML string or JSON string representing objects that will be converted into .NET objects.
- Thread - A separate set of executing code. While normal procedural code runs one line after the other, a separate thread will run at (apparently) the same time as another thread. Threads in reality are much more complex than this, but it is important to realise that threads are commonly used to prevent a subset of code blocking another subset.
Using the Code
The project exists of only a handful of classes, but revolves around one main one: the HttpHandler
. It is the class that sends information to a URL or retrieves information from it.
The main methods on the HttpHandler
are the Get
and Post
methods which correspond to the HTTP GET and POST methods, respectively. The Get
method can optionally take a Dictionary
of string
s to pass as parameters to the web method, while the Post
method must include parameters, as it is generally used to send data, not make a parameterless call to the server.
The RequestBuilder
class uses the URI and parameters (if any) passed to the Get
or Post
methods to create an HttpWebRequest
object. That object is then used by the HttpHandler
to make a call to the remote web server and return the server's response.
public class HttpHandler
{
//...
public HttpWebResponse Get(string uri, Dictionary<string, string> parameters)
{
builder = new RequestBuilder();
var request = builder.BuildRequest(uri, parameters);
//Wait for request to return before exiting
return ProcessRequest(request);
}
public void Post(string uri, Dictionary<string, string> parameters)
{
builder = new PostRequestBuilder();
var request = builder.BuildRequest(uri, parameters);
//Wait for request to return before exiting
ProcessRequest(request);
}
}
You may have noticed that there is a slight difference between the Get
and Post
method bodies. The Get
method uses a plain old RequestBuilder
, while the Post
method uses a PostRequestBuilder
. This is because there is an extra step when creating a POST request: writing the parameters to the POST stream. A GET request just utilises the query string portion of a URL to pass its parameters.
Each of these methods sends a blocking request to a Web Service - a request that waits until a response is returned before completing the method. This is often fine in code that runs locally, but there are many factors one must consider when utilising the unreliable medium that is the internet.
A response could be some time away depending on the web server, the distance to the server, the amount of data expected to be returned, etc. If you have a user sitting at a computer waiting for this to happen, it could get frustrating for them, so the best option is to do the calls asynchronously.
Thankfully, with .NET 4 (and the Parallel Extensions in .NET 3.5, which are a back-port of the functionality in .NET 4), it is really easy to run a method asynchronously using Task
s.
public class HttpHandler
{
//...
public void GetAsync(string uri, Dictionary<string, string> parameters)
{
builder = new RequestBuilder();
var request = builder.BuildRequest(uri, parameters);
//Don't bother waiting - if it is there, it is there
Task.Factory.StartNew(() => ProcessRequest(request));
}
public void PostAsync(string uri, Dictionary<string, string> parameters)
{
builder = new PostRequestBuilder();
var request = builder.BuildRequest(uri, parameters);
//Don't bother waiting - if it is there, it is there
Task.Factory.StartNew(() => ProcessRequest(request));
}
}
The above code does the same thing as the snippet previously, except that the method ProcessRequest
is run on a separate thread. The application doesn't wait for the response, it completes the method immediately after telling the Task library to fire off ProcessRequest
.
There are a few ways to handle the response once the request completes, but they can be tricky. The easiest way to do so is declare an event on the HttpHandler
and call it when the response is attained. This way, if another class subscribes to the event, it knows that there is a response to read when the handler is called.
public class HttpHandler
{
//...
public event EventHandler<genericeventargs<httpwebresponse >> RequestCompleted;
private HttpWebResponse ProcessRequest(HttpWebRequest request)
{
try
{
var response = (HttpWebResponse)request.GetResponse();
OnRequestCompleted(response);
return response;
}
catch (Exception ex)
{
var exception = new ApplicationException(String.Format(
"Request failed for Url: {0}", request.RequestUri), ex);
throw exception;
}
}
protected void OnRequestCompleted(HttpWebResponse response)
{
if (null != RequestCompleted)
RequestCompleted(this, new GenericEventArgs<httpwebresponse>(response));
}
}
In the above code, once the variable response
is assigned, a call to OnRequestCompleted
is made, which notifies any subscribers to the event that a response is ready.
N.B. The code is a little naughty in that it catches a blanket exception, but it is great for a simple, easy-to-read example.
Well, that is the guts of the HttpHandler
class. Now you need to know how to use it in your projects.
First, you need to add a reference to the library System.Net.CodeProject from within your project. Right click on 'References' in Solution Explorer:
Then select the Browse tab and navigate to where you have saved the library. You will want to select System.Net.CodeProject.dll.
And now you can use the HttpHandler
in code by importing it with the using
statement:
using System.Net;
Ok, hopefully you have a URL in mind that you want to make requests to, but if not, you can use the following one which is included in the sample project: http://graph.facebook.com/search?q=codeproject&type=post.
This URL gives you access to all publicly searchable posts on Facebook that are found with the query 'codeproject'. Breaking it down, we see there is the base URL http://graph.facebook.com/search and a query string with two parameters, 'q' and 'type'.
The following code is included in the attached project files, which also includes a simple way to process the HttpWebResponse
data, both synchronously and asynchronously using an event handler.
The HttpHandler
can be used as follows:
var handler = new HttpHandler
var url = "http://graph.facebook.com/search";
var parameters = new Dictionary<string, string>
{
{"q", "codeproject"}
, {"type", "post"}
}
var response = handler.Get(url, parameters);
Easy as that. Although the response is only an HttpWebResponse
at this point, the response stream still needs to be retrieved. From Facebook, the stream contains a JSON object containing all the fun stuff like the posts you asked for. Handling the stream is outside the scope of this article, but feel free to examine the code in the included files.
There is a big fat article here on HttpWebRequest
s and HttpWebResponse
s if you need a bit more information on them and how to use them.
Points of Interest
As this is a basic article, the asynchronous implementation of the Get
and Post
methods is also very basic. There is no IAsnycResult
returned or anything fancy, just an Event
to subscribe to that will notify when the request has completed.
History
- Version 1.0 - Article uploaded to CodeProject.