The Microsoft MVP Award Program Blog

Independent Experts. Real World Answers.

The Microsoft MVP Award Program Blog

Independent Experts. Real World Answers.

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

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

  • Comments 4

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? 

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":"http://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: 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.

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

  • "ASP MVC is inherently RESTful", is this a joke? ASP.NET MVC has nothing that enforces REST architecture, unlike rails or openrasta.

  • I'd concur with Roberto. MVC is not inherently RESTful. Sure you can plug-in some things to do so (which is what my intention with EasyMVC was), but out of the box it does need work.

  • I don't think any system enforces or is inherently RESTful - it's not something that you tick when you create a project. I don't have experience of Rails, but I've heard Sebastien Lambla (the main developer) say that OpenRasta helps you build a RESTful service, but you can just as easily build an unRESTful service with it. The same thing with ASP.NET MVC - you can build RESTful services with it, but it doesn't do it for you - you have to implement the RESTful style.

  • Thanks for your comments. When I say "inherently restful" - I mean that at ASP MVC's core, is the ability to standup resources that conform to REST. i.e., from a controller, I can expose endpoints that can render/consume xml or json rather easily. In fact, the json is pretty much out of the box, both with serializing and de-serializing via the model binders. Are there other tools out there? Of course, I still contend that as a general proposition, the MVC pattern itself is RESTful. Just because some things here and there require some additional work becuse you don't get it "out of the box", that does not obviate the fact that the tool does not have certain inherent characteristics. Compare to ASP.NET / Webforms. We wouild all agree that is not restul, and in general, the MVP pattern is not RESTful.

    Lee brings up a good point wherein with a tool that supports rest, you can create something that is not rest. You can work around must about any tool - and that includes Rails.. :-)

    The main point of this post was that if you have MVC and you need to expose data and you would like to have a descriptive way to either fetch or update data, those capabilities are pretty much in ASP .NET MVC - if not out of the box, its pretty darn close.  And from that, I asserted that MVC is restful, inherently or otherwise.

    One thing that I probably should have added was the difference between GET, POST, DELETE and PUT. Eventhough there is no official REST Standard (since it's really an architecture), it would appear that if such a standard existed, to be completely restful, one's app would have to support these verbs - and specifically, to honor the difference between POST and PUT. As I understand it, POST is for new entities and PUT is to edit/modify existing entities. i.e., if I have used GET to acquire an exiting resource, the process to update that resource should be a PUT - not a POST, and if I attempt a POST, I should get some error response. And of course, PUT and DELETE are idempotent - meaning that if I run the same operation 100x, it will be the same as if  did it 1x. POSTS are not necessarily idempotent, but as it turns out, our data layers pretty enforces any negative side effects (duplicate PK's, etc.) Then there is the whole response code issue. I believe PUTs are supposed to respond with a 301 (perm redirect). Again, I'm not sure if there are many who comply wtih all of these specifics.

    ASP MVC does respect all of these verbs out of the box. Practically though, I think most just rely on GET and POST - posts handling what would actually be puts and deletes in addition to what post would do. Nobody really called out that point and that would be a fair knock on the piece. This has given me some food for thought.

    Again, thanks for your comments..

    </JVP>

Page 1 of 1 (4 items)
Leave a Comment
  • Please add 4 and 8 and type the answer here:
  • Post