Using Sitecore MVC for REST Services

By December 9, 2014MVC, Sitecore

Sitecore neatly stores your content so you can manage your organization’s data easily. However, your content is behind bars if you’re not serving it via web services. Your data needs to reach a broad range of clients, including browsers and mobile devices that only RESTful applications can fulfill. In this post, I will show you how you can unleash your Sitecore data so you can provide your customers and users with rich, interactive applications. They expect nothing less in the post-mobile era and a world where JavaScript is all grown up!

Sitecore Cloud - Web Services

Sitecore MVC

Let’s face it, Web Forms is a dying breed. Although it served its purpose well for many years, the convoluted HTML that renders view states, mangled DOM elements, and cryptic JavaScript is not acceptable any more. This is where MVC came in and embraced the next generation of web development.

Ok, we know Web API is amazing. It’s a platform for building RESTful applications on the .NET Framework and was meant to be the ultimate unification initiative for REST Web Services in ASP.NET WCF, MVC and WebForms. To be honest though, it was an after-thought to an existing framework especially to some areas that are going obsolete. This is clear when you look into ASP.NET MVC 6. ASP.NET vNext merges MVC and Web API into one pipeline. Because of this, stick with MVC for building your REST services and you will have a smoother upgrade path to MVC 6. It gives you everything you need anyway. Starting from Sitecore 7.1, MVC has been made a first-class citizen so we are ready to rock and roll!

Sitecore Project

Ready to build our first REST service? There are a few fundamental pieces that need to be put in place to take us to the promise land. First, let’s build off the LaunchSitecoreMvc project so we have some sample data to work with. Next, we will create a class library that will house our web services to serve our goods. Below is a screenshot of the recommended structure of our solution.

Sitecore MVC Structure

LaunchSitecoreMvc.Api is where we will put our REST web services and LaunchSitecoreMvc.Core is where our generic classes and extensions will go.

In LaunchSitecoreMvc.Api, the Startup.cs file will be used to register and initialize our MVC and REST services. It can be thought of as the Global.asax file. This file will tap into your application’s lifecycle to allow us to register routes and other things.

The OnStart method is overridden to register your routes at the right time and will be triggered during the Application_Start of your application. We only want to register routes once, so it is important that this event is only triggered once. This is what RegisterStartup() does in the PreInit() method in our class. To make it possible to hook into the application lifecycle like this, System.Web’s PreApplicationStartMethod attribute is used to make this happen. Since the web application is referencing this library, this class will get injected into the application lifecycle by the .NET framework.

Sitecore REST Services

For the route registration, we will actually map the MVC route via route attributes instead. This will enable you to construct REST services by decorating your MVC actions with routes.

Once you have told .NET to pay attention to your route attributes, your controllers will look something like this:

This is awesome because I can stick with my server-side code conventions, while freely building a RESTful API using the action attributes. The RoutePrefix on the controller class itself is the root path for this controller. Then our actions are decorated with Route attributes to specify the rest of the path to listen for. With the example above, we will have the following URL’s for our web services:

  • ~/api/team/members
  • ~/api/team/members/3e241e52-3767-464d-b994-a776c8a060c3

Sitecore JSON Data

It is clear that Json.NET is the preferred way to serialize your data to JSON. It enables you to get around circular references, increase performance, and abstract serialization quirks like dates. It has stood the test of time and even Microsoft has vouched for it, so much that they keep promising to include Json.NET out of the box. Until then, we have to create a formatter for Json.NET so we can use it to serialize our data. Below is the code to create a formatter based on Json.NET:

Now in our controllers, we can use the Json.NET formatter by returning this in the action:

That can get tedious pretty quick, so let’s abstract this away into a BaseJsonController class. BaseController will inherit from this which is why TeamController can simply do this in the end:

Sitecore Models

One of the most powerful features in Sitecore is that content items have dynamic fields. The only downside to this is we must explicitly call our custom fields by its arbitrary string key which is unknown at compile time. Wouldn’t it be great if we had POCO models for our content types? Yes we can (really!):

Instead of returning the native Item object, the class is using the constructor for translating it to a leaner model. This way, we get a slimmed down version of the items without getting any unnecessary noise or confusion with our data. Eventually, we can use a mapper tool to do this, but that elegance may come at a cost of complexity so mileage may vary going down that road.

Sitecore Results

Ready to see the REST service data? Here is how the outcome will look like:

~/api/team/members:

Sitecore REST Results List

~/api/team/members/3e241e52-3767-464d-b994-a776c8a060c3:

Sitecore REST Results Item

Conclusion

Isn’t the above REST service data a beauty? There are some AngularJS, Kendo UI, and DevExpress apps that are hungry for that JSON data and ready to consume it!

Cookie Monster

We have uploaded the code samples for this post at GitHub: LaunchSitecoreMvc-RESTServices. Stay tuned for techniques in building JavaScript and mobile application consuming these web services.

Happy Coding!

The following two tabs change content below.
  • Pingback: Using Sitecore MVC for REST Services | Xamarin Fire()

  • James West-Sadler

    Hi, this is great. Have you managed to get this to work with 7.5 or 8? I’m having an issue where it seems to ignore MapMvcAttributeRoutes and then comes up with an error saying document not found.