Editor's Note: On September 13, 2011 Microsoft will kick off its first ever Build event. To toast this, the MVP Award Program blog will run a special developer series for the next few weeks for our MVP Mondays. The following is the first of this series, a guest post by Visual FoxPro MVP John Petersen.
John has been developing software for 20 years,starting with dBase, Clipper and FoxBase + thereafter, migrating to FoxPro and Visual FoxPro and Visual Basic. Other areas of concentration include Oracle and SQL Server - versions 6-2008. John is the Philadelphia Microsoft Practice Director for CEI America (www.ceiamerica.com), a Microsoft Gold Partner. From 1995 to 2001, he was a Microsoft Visual FoxPro MVP. Today, his emphasis is on ASP MVC .NET applications. He is a current Microsoft ASP .NET MVP. John was a co-author of Visual FoxPro Enterprise Development from Prima Publishing with Rod Paddock, Ron Talmadge and Eric Ranft. He was also a co-author of Visual Basic Web Development from Prima Publishing with Rod Paddock and Richard Campbell. In 2004, John graduated from the Rutgers University School of Law with a Juris Doctor Degree. He passed the Pennsylvania and New Jersey Bar exams and was in private practice for several years. Read John’s developer blog or follow him on Twitter.
You have heard it before that ASP MVC is “inherently RESTful.” But what exactly does that mean? In this blog post, I’m going to quicklyintroduce you to what REST is, why ASP MVC is “inherently RESTful” and how to retrofit your ASP MVC applications to expose their RESTfulness. To illustrate the concepts, I will be using the NerdDinner exemplar ASP MVC application that is available on CodePlex.com: http://www.nerddinner.codeplex.com/. The client used to demonstrate these capabilities will be simple HTML pages using jQuery. You can download jQuery from http://www.jquery.com. As of this post, the current released version is 1.6.2 which can be found at http://code.jquery.com/jquery-1.6.2.min.js.
What is REST?
ASP MVC and Nerd Dinner
If you have worked with ASP MVC, you are likely aware of the Nerd Dinner application which highlights the major features of ASP MVC. The problem domain is simple, we can create events for people to attend and people can RSVP. Creating and RSVP’ing to a dinner requires that you be logged into the application. Authentication is beyond the scope of this post. Matters concerning authentication will be addressed in a subsequent post. In this post, we will concentrate on two functions the Nerd Dinner Application supports: finding dinners near a certain locale and finding all upcoming dinners. The following illustrates the Nerd Dinner Application’s ability to find all upcoming dinners:
In MVC parlance, the Dinner Controller’s Index() action is invoked. The following is the code for that action:
The /Dinners/Index action returns a view that is made up of zero or more dinners. If no parameter is passed, a view that contains a paginated dinner list is returned. Just like Bing, this is a RESTful call. But what if all we want is the data? It would be nice if we could pass a URL like this: /dinners.json. As it turns out, some of this functionality is already in Nerd Dinner. If you review the search controller, you will find a GetMostPopularDinners action. In that action, you will find code that reformats the dinner model into a new structure and serializes the data as jSON. To give the Dinner’s controller that capability, we will copy the private jSonDinnersFromDinner method (with a slight modification) into the Dinners Controller (this of course is not DRY! I’ll leave it to you to refactor!!!)
Adding a Route
What an ASP MVC application can respond to is dictated by what is contained in the routing table – which is hydrated in the global.asax file. In order for Nerd Dinner to recognize the .json extension, we need to add the following code in the RegisterRoutes function in the Global.asax file:
Now, the application will recognize /dinners.json. Further, this route will not interfere with the other routes that are already established. We haven’t yet modified the controller, so the same view will still be rendered. Let’s fix that up now.
Modifying the Controller
First, let’s add a slightly revised version of the private JsonDinnerFromDinner method to the Dinner Controller:
Now that we have the ability to format the dinner object properly, let’s turn to the Dinner Controller and add a new JsonDinners Action:
The new route allows the ASP MVC app to respond to the /dinners.json request. The new JsonDinners() action supports that request. Note, there is a check to make sure the request is in the form of /dinners.json and not /dinners/JsonDinners. In the event the latter form is used, the controller will simply redirect to the index action. Now, when /dinners.json is invoked, the following data stream will be returned:
Code Camp Nerd
Dinner to celebrate another successful code
With a RESTful endpoint that serves up data, let’s put together a simple page that consumes the data:
In this example, the MVC application is being treated as an endpoint. jQuery is loaded from the Microsoft Ajax CDN. Once jQuery is loaded, we can then invoke jQueyr’s getJSON() method. Not the URL that is passed: http://localhost:48202/dinners.json. That is the new endpoint we created in the Nerd Dinner application. There are no parameters being passed (but we could easily outfit the method to handle parameters). The third parameter is a call back function. In this example, the jQuery each() function is invoked to cycle through the dinners. For each dinner, a link (wrapped in a p tag) is created and is appended to the dinnerData div.
Clicking a dinner link will invoke the Dinners Controller Details action, passing the dinner id that was used to construct the link. So then, how far can we go with this? The simple answer is that you can go as far as you want. With an exposed RESTful data endpoint, the dinner data can be more easily consumed by other applications. A good example of where this already occurs in the Nerd Dinner application is the facility that loads the map when the Nerd Dinner page first loads. The best way to understand what is going on is to add a few break points to the NerdDinner.js file located in the /Scripts folder. The following illustrates where you will want to place the breakpoints.
This scenario is not much different than the first example. A request is made which renders jSON data. In this particular case, a POST as opposed to a GET is used. Like the first example, jQuery is used to cycle through the data. In this example, the data is used to apply the map points. When you hover the mouse over a point, details regarding that event are displayed.