Skip navigation

Can Episerver Search Coexist with Default MVC Routes?

I was hitting a brick wall recently when implementing Episerver search.  I could see that items were being queued up to be indexed:

var searchStore = SearchSettings.GetDynamicDataStore();
if (searchStore == null)
{
    Debug.WriteLine("dds store is null.");
}
else
{
    Debug.WriteLine("store.Items().Count() = " + searchStore.Items().Count());
}

However, the queue wasn’t being processed.  The number of items should be zero once everything has been indexed.

First, I tried browsing to the /indexingService/indexingService.svc and got the expected “Endpoint not found” message in my browser: 

Endpoint Not FoundSo far, so good.  Next, I tried to hit one of the endpoints:  /indexingService/indexingService.svc/search/?q=videos&namedindexes=default&format=xml&offset=0&limit=50&accesskey=local

I expected to get a big xml dump of the search results, but instead I got a 404 response:

 404 Error

The first clue came from the Episerver log file.

ERROR SearchSettings: Update batch could not be sent to service uri 'http://localhost:51631/IndexingService/IndexingService.svc/update/?accesskey=local'. Message: 'The remote server returned an error: (404) Not Found.
2016-03-04 14:46:20,183 [41] ERROR SearchSettings: Send batch for named index 'serviceName' failed. Items are left in queue.
2016-03-04 14:46:50,219 [58] ERROR EPiServer.Global: 1.2.5 Unhandled exception in ASP.NET
System.Web.HttpException (0x80004005): The controller for path '/IndexingService/IndexingService.svc/update/' was not found or does not implement IController.

Notice that last message?  The site is thinking that the search endpoint is an MVC route.  I checked the site’s global.asax, and sure enough, standard MVC routes are being used in addition to the Episerver routes.

protected override void RegisterRoutes(RouteCollection routes)
{
    base.RegisterRoutes(routes);
    routes.MapRoute(
      name: "Default",
      url: "{controller}/{action}/{id}",
      defaults: new { action = "Index", id = UrlParameter.Optional });
}

When I take out the call to MapRoute, the endpoints start working:

Working Endpoints

I couldn’t just take that out, however, because other developers on my team were counting on that so that their custom AJAX web services would work.  In the end, this problem was solved with a call to IgnoreRoute. Take note of where this call is made, because it absolutely must come before the call to MapRoute; otherwise it just won’t work.

public class EPiServerApplication : EPiServer.Global
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
    }
    protected override void RegisterRoutes(RouteCollection routes)
    {
        base.RegisterRoutes(routes);
        routes.IgnoreRoute("IndexingService/IndexingService.svc/{*pathInfo}");

        routes.MapRoute(
          name: "Default",
          url: "{controller}/{action}/{id}",
          defaults: new { action = "Index", id = UrlParameter.Optional });
    }
}