Using MVC as a REST Service that is Accessed by jQuery/JavaScript

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: https://www.nerddinner.codeplex.com/. The client used to demonstrate these capabilities will be simple HTML pages using jQuery. You can download jQuery from https://www.jquery.com. As of this post, the current released version is 1.6.2 which can be found at https://code.jquery.com/jquery-1.6.2.min.js.

What is REST? 

REST stands for Representational State Transfer and it is a method for retrieving content from an HTTP endpoint. REST is not new having been around since HTML 1.0. The World Wide Web itself is the largest REST example. A server is at rest, waiting for a request. A client invokes a request from a resource that is identified by a Uniform Resource Locator (URL).  At that moment, the server is no longer at rest as it invokes the actions that are defined in the URL. The request is processed and returned to the client. The server goes back to its restful state.  REST’s most notable feature is that it is stateless. In other words, each call has all the necessary information for the server to process the request. These kinds of requests are known as HTTP GET requests. This is not to say the server can’t hold and manage state. We do this all of the time with sessions in IIS. Most of the time, when we make requests, the response is a combination of HTML markup, CSS, script (JavaScript/jQuery) and data. It’s all combined and presented in a browser, whether it is on your desktop, laptop, tablet or phone. If this is the only way to present your information, several limitations result. For one thing, you data presentation is locked into a specific implementation. It’s still RESTful, but from a separation of concerns standpoint, you have the classic monolithic application problem wherein your application is difficult to maintain, is not flexible, not amenable to change, etc. It’s far better to tease your application apart and a good way to start is to expose endpoints that just serve data. Let’s examine the Nerd Dinner application to see how we can achieve that goal.

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:

Instead of having the dinnerid as the URL, we will use the full address. Remember, this data may be consumed by a page that is not part of the same domain. In jQuery/JavaScript example that follows, the Nerd Dinner MVC Application is going to be treated as an HTTP endpoint – just like Bing. We need to outfit the data accordingly.

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:

[{"DinnerID":71,"EventDate":"\/Date(1318719600000)\/","Title":"Philly
Code Camp Nerd
Dinner","Latitude":0,"Longitude":0,"Description":"Nerd
Dinner to celebrate another successful code
camp","RSVPCount":1,"Url":"https://localhost:48202/71"}]

Accessing MVC Data with jQuery/JavaScript

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: https://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.

Conclusion

As you have learned, ASP MVC is inherently RESTful and it is relatively easy to set your applications up to take advantage of that feature. Even if you didn’t do so from the start, because of ASP’s MVC architecture, it is not difficult to retrofit your applications to expose endpoints that serve up data in either jSON or XML format. Once your application  serves up data in this way, technologies like jQuery and JavaScript can leverage that data. Further, it comes easier for other applications to consume your application’s data. Another good example of a RESTful API is Bing. Check out the Bing Developer Center: https://www.bing.com/developers. Applying these same concepts, jQuery and JavaScript can easily consume the Bing search results. In an upcoming post, I will discuss how to retrieve/update secured data that requires you to be authenticated.