Sitecore
Sitecore Service API Controller and custom routes
May 8, 2016
4

the 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 online and offline. Whilst it is very easy to create a custom route for a Service API Controller , there is not much information to be found and there are several ways to create a custom route. In this post i will cover one method: Adding a custom route using a processor in the initialize pipeline

One other method which you might use but which i do not recommend is the method described in the official documentation :  documentation. The information can be found in chapter 4.9.2. The reason i do not recommend this method is because you would overwrite the default routing. Which means you need to be very careful so you prevent making any default sitecore controller unuseable, this is also the reason why i am not recommending this approach and I am only mentioning it because it is in the official documentation. If you go against my advice and do choose this method and not the method in this blog post… please ensure you at least call the default mapper from the custom mapper so that you also have the default routing available.

Controller code used in this blog post

In this blog post i am reusing the code i have written in my previous blos post about Service API controllers. Please head over there if you haven’t already read that blog post.

What do you need to run the examples

To run the code samples in this blog post you need an additional dll comparing to my previous blog post. This dll is the “Sitecore.Kernel.dll”. The reason for the extra dependancy is that we need the pipelines namespace

Adding a custom route by adding a processor to the initialize pipeline

This method relies on Sitecore’s pipeline architecture to add a route to the routecollection. This method keeps every route, filter and security benefits of the Service API Controller intact and therefor does not pose any risk to the basic Service API Controller functionalities.

For this method to work we will need to start with adjusting the code sample from the previous blog post a little bit: we need to remove the [ServicesClient] attribute as it conflicts with the regular routing:

 
 public class ExampleController : ServicesApiController
    {
        [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;
        }
    }

Now that we are done doing the preperations we can go on to the next step: creating the processor which we will patch into the Sitecore Initialize pipeline. This processor will use the regular Web API routing mechanism to add the route to the routing tables:

using Sitecore.Pipelines;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;

namespace Derk.Blog.Api.Processor
{
    public class RegisterRoute
    {
        public void Process(PipelineArgs args)
        {
            GlobalConfiguration.Configure(Configure);
        }
        protected void Configure(HttpConfiguration configuration)
        {
            var routes = configuration.Routes;
            routes.MapHttpRoute("BlogApi", "sitecore/api/blog/{controller}/{action}/{id}", new
            {
                controller = "Example",
                action = "BlogPost",
                id = 1
            });
        }
    }
}

This piece of code adds a route which for the Example controller would look like “http://localhost/sitecore/api/blog/Example/BlogPost/1”

Now that we have written the code needed to register the new processor we just need to patch it into the Sitecore Initialize pipeline. We will do that with the following config patch file:

 
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <initialize>
        <processor patch:after="processor[@type='Sitecore.Pipelines.Loader.EnsureAnonymousUsers, Sitecore.Kernel']"
        type="Derk.Blog.Api.Processor.RegisterRoute, Derk.Blog.Api" />
      </initialize>
    </pipelines>
  </sitecore>
</configuration>

After publishing the config file and code correctly you will be able to reach your Service API Controller on your new route:

route 1

Leave a Reply

4 comments

  1. That’s great thanks!

  2. Hi Derk Hudepol
    Thanks for posting great helpful article.After following your way i have implemented web api but i am facing an issue and don’t know how to resolve it .

    The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application’s startup code after all other initialization code.

  3. Hi Derk,
    Is it possible to host the API outside the Sitecore folder? To be more specific, we have hosted our instance on Azure App Services using Sitecore Azure toolkit where, you would have the following two different App Services.
    1) App Service for Content Management
    2) App Service for Content Delivery – This would be accessible for general public and so access to “Sitecore” folder is restricted.
    Our requirement is to create a Service API Controller on CD (#2 above) and give access to some third party vendor who use the API. Is it really possible to host the API outside the Sitecore folder?

    1. Hi Praveen,
      Sure, you are free to use any route you would like to have.

      Just change “BlogApi”, “sitecore/api/blog/{controller}/{action}/{id}” to any url you would like to have like per example “BlogApi”, “my-non-blocked-api-route/api/blog/{controller}/{action}/{id}”

      It should not pose any problem.

      Kind regards,
      Derk