The Truth About HttpHandlers and WebApi

In 2012 when Microsoft introduced the ASP.Net WebAPI, I initially became confused about yet another way to generate and transmit content across a HttpRequest.  After spending some time thinking about WebAPI over the past week or two and writing a few blocks of sample code, I think I finally have some clarity around my confusion and these are those lessons I learned the hard way.

Old School API – SOAP and ASMX

When ASP.Net launched, the only framework to create and publish content that was available was WebForms.  Everybody used it, and it worked well.  If you wanted to create an interface for machine-to-machine communications you would create a SOAP service in an ASMX file.  You could (and still can) add web references to projects that reference these services.  The web reference gives you a first class object with a complete API in your project that you can interact with.

Over time, it became less compelling to build the SOAP services as they transmitted a significant amount of wrapper content around the actual payload you wanted to work with.  This extra content was messy, and other programming languages didn’t have the tooling support to manage them well.  Developers started looking for less complicated alternatives to communicate with connected clients.  It turns out that there was another option available that was overlooked by many: HttpHandlers.

HttpHandlers in ASP.Net

HttpHandlers are the backbone of ASP.Net.  An HttpHandler is any class that implements the IHttpHandler interface, handles an incoming request, and provides a response to webserver communications.  IHttpHandler is a trivial interface with the following signature:

 

    public class TestHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            // TODO: Implement this method
            throw new NotImplementedException();
        }

        public bool IsReusable
        {
            get
            {
                // TODO: Implement this property getter
                throw new NotImplementedException();
            }
        }
    }

Listing 1 – Simple IHttpHandler interface implementation

The ProcessRequest method is where we can insert our code to handle all data being requested of the handler and all data to respond from the handler.  The IsReusable property is often misunderstood, but has a simple definition: Should an instance of this handler be re-used for other requests to the webserver?  If the return value is false, a new version of the handler class will be instantiated for each request to the server.  If IsReusable returns true, then the same instance will be used for all requests to the server.  A simple implementation that outputs some of my favorite sports teams in XML format might look like this:

public class MyHandler : IHttpHandler
    {


        public readonly static IEnumerable MyTeams = new List
        {
            new Team { City = "Philadelphia", Name = "Phillies" },
            new Team { City = "Boston", Name = "Red Sox" },
            new Team { City = "Cleveland", Name = "Browns" },
            new Team { City = "Houston", Name = "Astros" },
            new Team { City = "San Diego", Name = "Chargers" }
        };

        #region IHttpHandler Members

        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/xml";

            context.Response.Write("");

            foreach (var t in MyData.MyTeams)
            {
                context.Response.Write("");
                context.Response.Write("");
                context.Response.Write(t.City);
                context.Response.Write("");
                context.Response.Write("");
                context.Response.Write(t.Name);
                context.Response.Write("");
                context.Response.Write("");
            }

            context.Response.Write("");

        }

        #endregion
    }

Listing 2 – A Sample XML Generating HttpHandler

Some developers get confused about the difference between a class that implements IHttpHandler and an ASHX file.  These are very similar things, but different with their own advantages.  An ASHX file is an IHttpHandler whose end-point is defined by the name of the ASHX file.  If you create foo.ashx you can trigger the ProcessRequest method by navigating to http://localhost/foo.ashx  Conversely, a class that implements IHttpHandler needs to be registered in web.config with a path and file-extension end-point to answer to.  The format of this registration lies within the system.webServer section of web.config:


    

        

    
  

Listing 3 – Web.Config entries for an HttpHandler

Further instructions on how to configure the HttpHandler is available on MSDN

Both of these types of HttpHandlers are easy to implement, and put you right on the metal.  You are handed and HttpContext and you can do anything you want to handle the incoming request and respond to it.  If you are working with some low-level operations such as inspecting HttpHeaders for responses, you may choose to go this route.

ASP.Net WebAPI in a nutshell

Scott Guthrie describes ASP.Net WebAPI as a technology that allows developers to build powerful web based APIs that have the following 9 core capabilities:

  • Modern HTTP Programming Model – Directly access the HTTP requests and responses using a strongly typed HTTP object model
  • Content Negotiation – Built in support for content negotiation, which allows the client and server to work together to determine to correct data format to return from an API
  • Query Composition – Easily supports OData URL conventions when you return a type of IQueryable<T> from a method
  • Model Binding and Validation – Supports the same model binding available in WebForms and MVC
  • Routes – You know ’em, you love ’em… they’re all over ASP.Net.  Why WOULDN’T you expect them in WebAPI?
  • Filters – You can apply similar filters to those that you create for MVC
  • Improved Testability – WebAPI uses two new objects called HttpRequestMessage and HttpResponseMessage to make unit testing significantly easier.  
  • IoC Support – The same service locator pattern implemented in ASP.Net MVC is available to inject dependencies into your API implementations
  • Flexible Hosting – Web APIs can be hosted within any type of ASP.Net application.  You can also host it within any process if you don’t want to engage IIS to host your API.

The quick and dirty summary of this list is that WebAPI functions, looks, and feels like developing with ASP.Net MVC.  There are a few simple differences between them, but once you learn them, its very easy to progress quickly.

The Super-Duper Happy Sample

To implement a simple service that outputs a collection of values when a GET is called with no arguments (eg: http://localhost/api/Values ) you need to add very little to get started.  First, add a WebAPI controller to your website by selecting the appropriate item in the Add Item dialog box:

The default implementation delivered looks like the following:

    public class ValuesController : ApiController
    {
        // GET api/<controller>
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/<controller>/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/<controller>
        public void Post([FromBody]string value)
        {
        }

        // PUT api/<controller>/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/<controller>/5
        public void Delete(int id)
        {
        }
    }

Listing 4 – Default API Controller implementation

With this simple implementation you can navigate your browser to http://localhost/api/values and get the two values “value1” and “value2” returned in XML format.  If you programatically request that address and change your “accept” header to “text/json” you will receive JSON in the response stream.  You can PUT, POST, and DELETE content to this controller and the appropriate action methods will be triggered based on the HTTP action executed.  

The Truth

WebAPI is just another HttpHandler, one that has been wrapped around all sorts of helpful content management and negotiation technologies as Scott Guthrie suggested.  You certainly could cut out all of those other technologies and benefits and code directly “on the metal” with an HttpHandler, and that was the only choice you had until 2012 and ASP.Net 4.  In today’s web community, its best to use RESTful methods and use a standard format like XML or JSON to transfer data.  HttpHandlers had their place, but going forward, I’m going to use WebAPI whenever I need to transmit data over HTTP to browsers or any other connected client.

Adding SignalR to an ASP.Net WebForms Project

In this post, I want to demonstrate how you can add real-time interactivity to a website that is written with ASP.Net WebForms.  I’m going to show you how easily and quickly you can have SignalR update the content of a standard ListView webcontrol to show a ‘live’ log of events on your webserver.

UPDATE Jan 28, 2013: I have uploaded the source to this post to my GitHub account.  Go get some sample code!

Project Setup

For this sample, I’m going to start up a standard ASP.Net WebForms application with .Net 4.5  Once the project is created, I’m going to clear out the default content on the home page and insert my ListView control as shown in Code Listing 1:

<asp:content runat="server" id="BodyContent" contentplaceholderid="MainContent">

    
    <h3>Log Items</h3>
    <asp:listview id="logListView" runat="server" itemplaceholderid="itemPlaceHolder" clientidmode="Static" enableviewstate="false">
        <layouttemplate>
            <ul id="logUl">
                <li runat="server" id="itemPlaceHolder"></li>
            </ul>
        </layouttemplate>
        <itemtemplate>
            <li><span class="logItem"><%#Container.DataItem.ToString() %></span></li>
        </itemtemplate>
    </asp:listview>

</asp:content>

Code Listing 1 – Initial layout of the ListView

With this block configured, I can write a small snippet in the code-behind default.aspx.cs file to load some log information from some other datastore.  For this example, I’m just going to bind to a List of strings to demonstrate the mix of server rendered content and dynamically added content:

        protected void Page_Load(object sender, EventArgs e)
        {

            var myLog = new List();
            myLog.Add(string.Format("{0} - Logging Started", DateTime.UtcNow));

            logListView.DataSource = myLog;
            logListView.DataBind();

        }

Code Listing 2 – Code behind to load some rendered data

I should now be able to start my application and see a simple pair of lines added to the default page that appear something like this:

Figure 1 – Static Log Content

Adding SignalR to the mix

At this point, we need to add SignalR to our project through the NuGet package manager.  I prefer to use the ‘Manage NuGet Packages’ dialog window to add these packages, so I add the packages for SignalR by searching for and adding the “Microsoft ASP.Net SignalR JS” package and the “Microsoft ASP.Net SignalR SystemWeb” packages.  At the time of this article’s writing, these packages are available in the ‘Pre-Release’ state only.

When you craft code for SignalR, you need to write client-side and server-side code.  The server-side code in this sample will be housed in a SignalR Hub.  

A hub is a structure that facilitates simple communications to a collection of client systems that are listening for commands to execute.  

In this project, we will create a LogHub class in c-sharp that will allow log messages to be communicated to all listening client browsers.  To simulate the repeated creation of log messages, I will use a timer to periodically transmit messages.  The code for the LogHub.cs file appears below:

    public class LogHub : Hub
    {

        public static readonly System.Timers.Timer _Timer = new System.Timers.Timer();

        static LogHub()
        {
            _Timer.Interval = 2000;
            _Timer.Elapsed += TimerElapsed;
            _Timer.Start();
        }

        static void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            var hub = GlobalHost.ConnectionManager.GetHubContext();
            hub.Clients.All.logMessage(string.Format("{0} - Still running", DateTime.UtcNow));
        }

    }

Code Listing 3 – LogHub source code

This hub contains 1 static event handler to listen for the timer’s elapsed event.  The first statement of this method gets a reference to the singleton LogHub that is running in our web server.  The next statement issues a message to all clients using the “hub.Clients.All” structure.  This is an interesting piece of code, as the “All” property of “hub.Clients” is a dynamic object.  The “All” property is a proxy for the objects and their methods that are available to be called over the SignalR pipeline.  

The object that is called over the SignalR pipeline by “All” from Code Listing 3, will be constructed in JavaScript and exposed to our hub in the following script block:

<script src="Scripts/jquery.signalR-1.0.0-rc1.min.js"></script>
<script src="/signalr/hubs" type="text/javascript"></script>
<script type="text/javascript">
    
    $(function() {

        var logger = $.connection.logHub;

        logger.client.logMessage = function(msg) {

            $("#logUl").append("<li><span class="logItem">" + msg + "</span></li>");

        };

        $.connection.hub.start();

    });

</script>

Code Listing 4 – JavaScript to log messages

There are a few pre-requisites here that I need to discuss first.  In my sample project, there is a reference to the jQuery library in my layout page, if you do not have that reference available, I recommend you add it to simplify the volume of JavaScript code you will be writing.  Next, I have added script references to the “jquery.signalR” library to give us access to the SignalR functionality.  The second reference is to a “magic URL” at /signalr/hubs.  This is a virtual location that exposes the methods that the hub classes have in public scope.  These methods can be called from the browser, through the plumbing established in this file.

The JavaScript in this listing is a normal jQuery enclosure, to ensure its contents do not get executed until after jQuery is loaded.  The first line gets a reference to the LogHub object that we created in listing 3.  We then connect a function to our client’s “logMessage” property.  This is the same function that is referenced in listing 3’s dynamic “All” object.  Thankfully, since we marked our ListView object with a static ClientIDMode and disabled ViewState, there are no hoops for us to go through to get a reference to the DOM objects that were created.  In this case, we’re simply going to append a list item (LI) to the unordered list (UL) with the message submitted to the function.  The last line of this enclosure is very important.  The start() method must always be called in order for SignalR to know to start listening for invocations from the server.

Before we can run our sample, we need to add one last piece of plumbing.  We need to tell the server to expose that magic URL at “/signalr/hubs”.  This is accomplished by adding a line to the Application_Start event handler in global.asax.cs:

void Application_Start(object sender, EventArgs e)
{
    // Code that runs on application startup
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AuthConfig.RegisterOpenAuth();

    RouteTable.Routes.MapHubs("~/signalr");

}

Code Listing 5 – Mapping the Hubs Route

Once this line is added, we can start our application.  You should see a result screen similar to the following:

Figure 2 – Static and Live Log Content

Summary

With a few simple settings on our WebForms project and the controls I wanted to modify for this sample, I was able to dramatically simplify the SignalR interactions with WebForms.  In this case, I didn’t run into any issues with the parts of WebForms that developers try to avoid like PostBack, Page Lifecycle, ViewState, and ClientID rendering.  Next time, we’ll confront those issues head on as I’ll show you how to interact between SignalR and controls that post back to the server.

Agile Development and Professional Development Teams

I’ve been an avid reader and follower of Agile Methodologies since 2003 when I read “Teach Yourself Extreme Programming in 24 Hours“.  This short and simple book laid the groundwork for my entrance into Extreme Programming and eventually a Scrum team approach to software.

In recent years, many organizations have embraced the Scrum methodology.  The big promises management hears are:

  • Developers will produce more code in a shorter amount of time
  • You can change your in-house applications more easily
  • Defect rates will go to zero

All very good things.  But these results are impossible to achieve if the development team is not staffed with professionals.  

“Uncle” Bob Martin visited the Philly.Net usergroup in December 2012 and shared with us his thoughts on what makes up a professional development team:

Demanding Professionalism: Uncle Bob @ Philly .NET User Group (PLUS WordWrap Kata) from 8th Light on Vimeo.

5 New Years Resolutions for this Developer in 2013

As I look forward to 2013, I have nothing but hope and joy for the things that I look to accomplish over the next 12 months. As a developer, I put together a list of 5 things that I should accomplish this year. None of these are a given, but they are all thing that I feel are within reach in the year ahead.

1. 100 Blog posts in 2013

I want to write a minimum of two technical blog posts a week. There is enough technical content to be documented and shared that this should be a very attainable goal. Some of these 100 posts will appear here on csharpfritz.com and some will also appear on blogs.telerik.com Either way, YOU my dear reader benefit from more FREE technical content.

2. 20 Speaking engagements

Over the course of the last year, I gave 8 sessions at user groups, code camps, and conferences. Over the course of the coming year, I’d like to double that number. You should see me at approximately 2 events a month, and I hope they aren’t all concentrated on the mid-Atlantic region of the United States.
I’d like to get at least 1, preferably several of these speaking engagements outside of North America. There are opportunities for me to engage in Europe, and I want to capitalize on at least one of those events.

3. 6 Webinars / Screencasts

I issues a screencast in July on this website where I demonstrated a technique in developers writing unit tests with the Nancy web framework. This was an exercise I thoroughly enjoyed, and would like to issue more screencasts on testing techniques, Asp.Net development tips and tricks, and other .Net goodness. I’d like to deliver on this promise at least every other month. You will find all of this content for FREE on YouTube.

4. Bring Webforms Back in Style

Many Asp.Net developers have been migrating away from the original Asp.Net webforms architecture. This is not a bad development technique, nor is it deprecated by Microsoft in any way. I want to write enough documentation and give enough presentations that demonstrate the advantages of webforms compared to other Asp.Net techniques to keep webforms in the forefront of your mind when you choose to build your next web application.
This goal is a true test of the scope of my influence, and will be tested as Microsoft grows and evolves the Asp.Net and Windows Azure platforms. To truly accomplish this goal, I will need to engage representatives at Microsoft and receive their approval in the type and style of content that I deliver.

5. Write a book

This is the big one… this goal is the furthest reach for me. Each of the other goals are things that I need to keep pace with over the course of the year. I want to compile my experiences and engage a publisher, or self-publish on Amazon. There are many things that I have learned from my years of designing and building large scale multi-tenant, software-as-a-service applications that I think the development community would really like to hear. If I want to keep to some sort of a schedule to complete this in the course of 2013, I should have a first draft ready by June 1. That should afford me enough time to publish by October 1. We will see how this goal progresses, as it is the one I am most excited about.

Conclusion

That’s it, my 5 developer resolutions or goals for 2013. Its an ambitious list, but I think its one that I can cover more of in the year ahead. I encourage you to follow along with me as I pursue this list. More details about my engagements and upcoming schedule will always be posted on the events page of this site.

My Top 6 Moments of 2012

It’s New Years Eve here in the Philadelphia area, and like many others, I’m reflecting over the past twelve months. 2012 has been an amazingly great year for me. I’m going to count down the top 6 moments that affected me over the past 12 months.

6. QUnit-Metro launch

In April and May of this year, I attended a handful of Windows 8 developer training events. At each of these events I learned a lot about how to create a Windows 8 application with HTML and JavaScript. However, I am very much a developer who has embraced the test-driven development mindset. At each one of these events I faced the same challenge again and again: How do I test this JavaScript code that I am writing for Windows 8?

I challenged myself then and there. I took the evening after one of these training events and attempted to utilize the qUnit test framework with Windows 8. After some tinkering, hacking, and a bit of luck, I got unit tests to run inside of the Metro environment. I cleaned up my changes and published them as a fork of the qUnit framework that I called “qUnitMetro”. This was the first project that I successfully forked and shared source code for. The amount of attention that this little project would get over the next few months was astonishing.

5. Joined Telerik

After a long journey that spread across the US East Coast from Orlando to Philadelphia, to Boston and back, I started my employment with Telerik on December 3rd. This journey to join Telerik was an amazing ride, meeting and interviewing with people that I knew from Code Camps, User Groups meetings, and some that I had never met but had heard on podcasts. I was genuinely excited to be counted as one of their peers and join this amazing organization.

I’m now a month into working at Telerik, and you should be seeing my name starting to appear more and more around the Asp.Net community. I promise you, I have a lot more to share and show. Over the next year, you should see me at a number of large events and perhaps at a Code Camp or two near you. Keep up with me here and on my Telerik product blog at: http://blogs.telerik.com/AjaxTeam

4. Code Camp NYC

At the beginning of September, I attended and spoke at Code Camp NYC. This was the first big code camp that I was traveling to speak at. Furthermore, I was spending my own money to get there. By financing the whole trip myself, I made myself more critical of my experience. I wanted to really figure out if this was it, if I was ready to do more as an INETA speaker.

The trip to New York was simple, a train ride from Philadelphia to Penn Station. As I was disembarking the train, I coincidentally ran into another Philly area speaker who was attending the event: John Petersen. Our discussion during the walk to the Microsoft office in Manhattan was refreshing and really opened my eyes to what my place could be in the developer community. The day I spent at that event, meeting the other speakers and interacting with the New York area developers helped convince me: I can travel and present technical content anywhere.

3. My June Trip to Vermont.Net

In June, on the Monday after Tech Ed 2012 in Orlando, I travelled to Burlington, Vermont to speak to the Vermont.Net user group. This was my first “INETA trip” to speak to a user group. I flew out of JFK airport in New York, landed in Burlington and took a brief walking tour of some of town. After an ice-cream at Ben + Jerry’s, I rode to the user group meeting in nearby Winooski. My topic for this meeting was a (very brief) introduction to the concepts of CQRS architecture. I was nervous that evening, and rambled through the complex content a bit fast for my own liking. After some re-enforcing words of confidence from some of the attendees like Julie Lerman, Rachel Reese, and Rob Hale as well as some of the other attendees, I felt confident that I could do this type of travel and speaking again.

It was at this point, that I decided to give the autumn code camp circuit a try. I booked my September event to Code Camp NYC, the September monthly meeting at Philly.Net, and Vermont Code Camp. These three events in 6 days were an amazing confidence booster to me, one that I will never forget.

Honorable Mention – Vermont Code Camp

After I submitted my talk for September at Vermont Code Camp, I arranged for it to be a nice vacation weekend with my wife. I sent the kids off to my parents for the weekend and found a nice hotel to stay at. What was most amazing for me about this weekend was not just the time I had to wander around Vermont with my wife, but the speaker dinner on the evening of the event.

Here I was, at a dinner table with these other volunteers and personalities from the .Net community, and my wife was along for the ride. I was entirely shocked and pleased with how quickly my colleagues welcomed my wife and the conversations that continued well into the late evening. A special thank you to Mike Jones, Julie Lerman, and Kathleen Dollard for a great evening of conversation. My wife will never forget discussing hiking boots in Ben + Jerry’s with Julie and Kathleen, one of those cool personal moments that this community has enthralled me with.

2. Speaker Idol at Tech Ed 2012

In May, after my trip to Tech Ed was approved by my employer, I got this crazy idea: Is there going to be a “Speaker Idol” competition at Tech Ed? If there is, why couldn’t I enter?

After a flurry of emails to the organizers, some of which I’m sure made me look like a stalker, I got my invite. They knew of me, and offered me a slot to speak on the first day of competition. I was absolutely thrilled with the opportunity, and was ready to face the judges and whatever issues may come. I worked for a week straight getting content about my qUnitMetro project ready. Windows 8 and Visual Studio 2012 were in beta testing, so I would be demonstrating something that NO ONE had seen before. I could break new ground and set myself apart as a knowledge leader… I tuned and tweaked, wrote blog posts, wrote sample code and slides. A week’s worth of sleepless nights to test and verify and get ready for a competition that COULD put me on the map, gain me significant notoriety in this community in a very short amount of time.

And then it happened… 4 days before Tech Ed, Microsoft released a new beta version of Windows 8. They were so generous in their beta testing release schedule, they released a new version of Visual Studio on the same day.

On this day my local user group was hosting a prominent speaker who was in Philadelphia for one night only. I didn’t take that evening to investigate the new Windows release, but instead attended the guest speaker’s lecture at a local community college. I swapped phone numbers with him, and asked for a few minutes of his time to discuss my talk for Speaker Idol. He was very generous with his time, and I can not thank him enough. It’s my hope that as a Developer Evangelist for Telerik that I can meet this example he set forth for me.

The next evening, I did my download of the new Windows 8 and Visual Studio code. It was then that my heart sank… My code didn’t work, my samples were invalid. I had to verify everything I had written up to that point. qUnitMetro needed to be reviewed, my samples for the Speaker Idol demo had to be verified… all in the course of 3 days.

After 2 days, a case of Mountain Dew, and a bit of cursing at my unknown Windows developer friends at Microsoft, I got my content straightened out. I realized the problems were my own, and got myself set to go for Orlando – site of Tech Ed 2012.

You can search this blog for a thorough retelling of how Speaker Idol went for me. I was as excited as a kid on Christmas morning, awaiting the experience. I spent so much valuable time at Tech Ed with a significant number of community leaders, and really felt like I was stepping up my game as a speaker. I got the buzz.. and was so comfortable on stage, that I started to really embrace the speaker experience.

Over the following month, I was on several podcasts and interviewed by CodeProject.com to discuss qUnitMetro. It was a great leap for me, and little did I know where it was going to take me. Several of the judges and a significant number of my friends who worked at Telerik saw my presentation at Tech Ed and were impressed. Little did I know that this would be the first step in my next adventure with my career.

1. Shipped the First Version of a New Web Application

If you’ve stayed with me through this detail of personal drivel, then I thank you.

I’ve made my number one event over the past year the shipment of production code, the launch of a new software-as-a-service web application. This was a product that I had designed from scratch. We were embarking on the use of dynamic view models, HTML5 offline-mode, and the use of NoSQL databases. We were trying new technologies that were supposed to help solve the business problems my application had.

Any time you ship code no matter how small it is, is a very big thing. If customers are using code you wrote, that’s a very big thing. If you write code and no one (including you) learns from it, no one is using it, or no one is paying you for it, you are wasting your time.

I’m proud of the team that I led that launched this application. We spent many long evenings getting it working properly, and were happy with how it ran. We were a scrum team that ran very well within all of the definitions of the scrum process. Our innovations even led the organization to file a patent based on my designs. That patent application is still pending today.

Conclusion

That’s it.. a whirlwind 2012 experience. I end the year working for a new company that is recognized around the world. I’m writing more and more technical content in blogs for you in the developer community. Next up: my resolutions for 2013 – What exactly can I accomplish in 2013?