Sitecore
Leveraging the ServicesApiController : Implementing a Sitecore Service API Controller
December 3, 2015
9

As of Sitecore 8 it has become very easy to implement a secure Web API using Service API Controllers. Since there is not a lot of information to be found around this topic the coming blog posts will be focused on providing the information you need to get started with Sitecore Service Controllers.

What is a ServicesAPIController?

A Services API Controller comes from the Sitecore.Service.Infrastructure dll and is just like a regular Web API controller except for the added benefits of the security and filter options which come the Sitecore.Service.Client. Even if you are looking to just create a Web API controller, the Services API Controller can be of use to you since no customizations to Sitecore are regularly needed to implement a controller.

Getting Started

What do you need to get started? Well actually not that much! The pre requisites are the following:

  • Sitecore.Service.Infrastructure.dll referenced in your project
  • The .net Web API dll’s like System.Web.Http. The easiest way to add these to an existing project is to install the nuget package: Microsoft.AspNet.WebAPI.
  • A Sitecore 8 installation
  • Optional: Sitecore.Services.Core.dll referenced in your project. This dll is only needed when you do not want to add a custom route to your Sitecore solution, by using the DLL it allows you to use the default Sitecore.Services.Client routing

After making sure you got both of the above requisites you can start creating your first Services API Controller. This is done by adding a regular controller to you project, which can be done by right clicking the folder you want to place your controller into and then selecting “Add Controller”:


Figure 1 adding regular controller to project

Now that we have a regular .net controller we can easily convert this to a ServicesAPIController. How to do this? That is the easy part, you can do this by adding inheriting the ServicesApiController, in my case:

 
using Sitecore.Services.Core;
using Sitecore.Services.Infrastructure.Web.Http;
using System.Web.Http;

namespace Hudepol.SSC.Web.Controllers
{
    [ServicesController]
    public class ExampleController : ServicesApiController
    { // GET: Example 
        public ActionResult Index()
        {
            return null;
        }
    }
}

What you can also see in my code is that I am using the [ServicesController] attribute. The reason is that if we decorate our controller with this attribute we do not need to create a custom route, instead we are using the Sitecore.Services.Client routing which is the following:

http://host/sitecore/api/ssc/controller-namespace/{controller}/{id}/action.

For my example the URL would be “http://localhost/sitecore/api/ssc/Hudepol-SSC-Web-Controllers/Example/{id}/Action” . Please note that the namespace “.”characters have been replaced by “-” characters and that I left out the controller part of the controllers name.

If you want to use this routing you need to reference the Sitecore.Services.Core.dll file in your project.

Note : if you create a default MVC controller please ensure you do not have the using “using System.Web.Mvc;” in your file but to have “using System.Web.Http;” instead. Else you will have problems when using attributes like [HttpGet]. This is because System.Web.Mvc is meant for regular Mvc controllers and the System.Web.Http is meant for WebApi controllers

Finishing the example

To help you get a grip on implementing a ServicesAPIController I have finished the example below:

using Sitecore.Services.Core;
using Sitecore.Services.Infrastructure.Web.Http;
using System.Dynamic;
using System.Web.Http;

namespace Hudepol.SSC.Web.Controllers
{
    [ServicesController]
    public class ExampleController : ServicesApiController
    {

        // GET: using url http://localhost/api/ssc/Hudepol-SSC-Web-Controllers/Example/{id}/BlogPost
        [HttpGet]
        public dynamic BlogPost(int id)
        {
            dynamic returnValue = new ExpandoObject();

            returnValue.id = id;
            returnValue.Title = "ServicesAPIController";
            returnValue.Body = "A very interesting blog post";

            return returnValue; 
        }
    }
}

What you can see in the code is that i am using the ExpandoObject class to instantiate my object. This is not best practice because it is not a strongly typed class. Instead it is the same dynamic class used for the Asp.NET ViewBag property. I am using it here to allow for a simple example everyone can use.

The result when calling the url “http://localhost/sitecore/api/ssc/Hudepol-SSC-Web-Controllers/Example/{id}/BlogPost” is:

Figure 2 Result of example


Important when externally accessing the service

If you want to acces your newly created service from an other machine than your localhost, per example when you are calling it from javascript in a client browser, it is important to know that by default that is not possible. There are security settings in play which control this bevahiour which I will not cover right now but plan on covering in the near future.

For now know that you can solve this by patching in the following by using a config file in the sitecore config include folder:

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <api>
      <services>
        <configuration type="Sitecore.Services.Infrastructure.Configuration.ServicesConfiguration, Sitecore.Services.Infrastructure">
          <allowedControllers hint="list:AddController">
            <allowedController desc="ExampleController">Hudepol.SSC.Web.Controllers.ExampleController, Hudepol.SSC.Web</allowedController>
          </allowedControllers>
        </configuration>
      </services>
    </api>
  </sitecore>
</configuration>

In the configuration above the “allowedcontroller” line is the most imporant. This line adds the controller to the list of api’s which can be accesssed externally, however this does not mean it does not use the filters and security features the ServicesAPIController offers.

Conclusion

This post covered the basics of setting up a Web API using the ServicesAPIController in Sitecore. There is a lot more you can do concerning the configuration en security of the ServicesAPIController however i will not cover those in this blog post.

Leave a Reply

9 comments

  1. This is an outstanding article. Just what I was looking for to headstart. Thank you very much for sharing, specially for steps to enable access to WebAPI externally.

  2. Thank you! Do all requests need to include an id? Seems with that URL convention every Get() method would be required to have an id parameter.

    1. Hi Chris,

      when using the [ServicesController] attribute to cerate you would always need the id. However since a ServicesApiController in basis is still a WebApiController you can also create a custom route. This would allow you to define your own query string parameters and route requirements. An example on how to create a custom route can be found here : https://kb.sitecore.net/articles/700677.

      When creating a custom route , you can remove the [ServicesController] attribute since we use that to generate the url route used in my blog post.

      1. Hi, just to follow up on this thread. I attempted to use a custom route to point to my API controller. the Controller implements ServicesApiController as you showed. However, the stack trace essentially tells me SitecoreControllerFactory.CreateController() cannot create my Controller because it does not implement IController. IController is for standard Controllers. Any idea what I’d be doing wrong here? Thanks for any help.

        1. Hi Chris,

          I will configure a route during the weekend and give you an example on how to configure the route. The example I gave you is referring to a route for a regular MVC controller and not for a Web API controller. Since they have separate route tables, this is probably the issue.

        2. Hi Chris,

          Because i wanted to give complete answer i have actually writting a blog post about this, the post can be found here : http://hookedon.digital/2016/05/08/sitecore-service-api-controller-and-custom-routes/

  3. […] reason for writing this blog post is that after my previous blog post about Sitecore Service API Controllers i have received questions about how you can implement a custom route for these controllers both […]

  4. typo: Sitecore.ServiceS.Infrastructure.dll