6

I'm working in a Helix-ish solution on Sitecore 8.2.

I can't seem to register any WebAPI controllers. The routes are fine. I've dug pretty far into the GlobalConfiguration and determined that it's not even registering any of my controllers (GlobalConfiguration.Configuration.Services.GetHttpControllerSelector().GetControllerMapping().ToList() turns up 68 Controllers, none of which are mine)

  • The controller ends with Controller
  • it extends ApiController
  • I've added the registration to the initialize pipeline (patch:after="*[@type='Sitecore.Mvc.Pipelines.Initialize.InitializeCommandRoute, Sitecore.Speak.Client']")
  • It appears in DI (in case that matters)
  • Just in case, I added it as an <allowedController> under the <configuration/sitecore/api/services/configuration> section
  • The route is valid (it can resolve the route, it just can't find the class)

Config:

<pipelines>
    <initialize>
        <processor type="MySolution.Foundation.xDB.RegRoute, MySolution.Foundation.xDB" patch:after="*[@type='Sitecore.Mvc.Pipelines.Initialize.InitializeCommandRoute, Sitecore.Speak.Client']" />
    </initialize>
</pipelines>

<api>
    <services>
        <configuration type="Sitecore.Services.Infrastructure.Configuration.ServicesConfiguration, Sitecore.Services.Infrastructure">
            <allowedControllers hint="list:AddController">
                <allowedController desc="TestApiController">MySolution.Foundation.xDB.Controllers.TestApiController, MySolution.Foundation.xDB</allowedController>
            </allowedControllers>
        </configuration>
    </services>
</api>

Controller

public class TestApiController : ApiController
{
    public string Test()
    {
        return "Success";
    }
}

Registration File

public class RegRoute
{
    public virtual void Process(PipelineArgs args)
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
}

public class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "testapi",
            routeTemplate: "-/api",
            defaults: new { controller = "TestApi", action = "Test" });
    }
}

Result

{"Message":"No HTTP resource was found that matches the request URI 'https://mysite.dev/-/api'.","MessageDetail":"No type was found that matches the controller named 'TestApi'."}

Based off the error, it seems it found the route, but can't find the controller.

  • What happens if you register your pipeline processor after Sitecore.Cintel.Endpoint.Plumbing.InitializeRoutes, Sitecore.Cintel? Several of the processors after InitializeCommandRoute make big changes to the Web API configuration, so it's possible your changes are being overwritten. If that fixes it, you'll also need to add an HttpGet attribute to your Test action, otherwise you'll get another error about the requested resource not supporting the "GET" HTTP method. – Corey Smith Feb 6 '18 at 4:55
  • Registering it after that line did not work – Ben Lipson Feb 6 '18 at 13:57
  • Are you using a dependency injection framework other than Microsoft.Extensions.DependencyInjection? I've got a solution on a clean install of Sitecore 8.2 Update-6 with your code that returns a different error message than you're seeing due to a missing HttpGet attribute: Error message received at /-/api is: "Message": "The requested resource does not support http method 'GET'.". My solution also has 69 controllers registered (the 68 you mentioned + the custom one from your question), which makes me think something else in your Initialize pipeline is causing issues. – Corey Smith Feb 6 '18 at 14:26
5

Web API is apparently really aggressive when it caches API Controller types. I was able to fix my issue by doing the following:

  1. stop IIS
  2. kill the w3wps
  3. navigate to C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root and obliterate anything in this folder
  4. Make sure the registration of the route happens after processor[@type='Sitecore.PathAnalyzer.Services.Pipelines.Initialize.WebApiInitializer, Sitecore.PathAnalyzer.Services']

My understanding is the controller types are cached in an XML file: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\xxxxx\xxxxx\UserCache\MS-ApiControllerTypeCache.xml. For some reason, this file was not getting updated. Blowing away the cache removed the XML file and allowed the cache to be rebuilt.

1

Update your Api methods to add an [HttpGet] attribute or change the method name to Get() (and update your route initialization accordingly):

public class TestApiController : ApiController
{
    [HttpGet]
    public string Test()
    {
        return "Success from Test()";
    }

    public string Get()
    {
        return "Success from Get()";
    }
}

The current placement of the initialization pipeline processor is fine, just be aware that patching before/after the InitializeRoutes processors makes more sense depending on whether the calls should be tracked:

The Sitecore.Mvc.Pipelines.Loader.InitializeRoutes processor of the Initialize pipeline requires a session to be present for all routes. Therefore, if you add the custom route registration processor before the Sitecore.Mvc.Pipelines.Loader.InitializeRoutes processors, the session is available in the controllers.

If you register the routes in the processor that is initialized after the Sitecore.Mvc.Pipelines.Loader.InitializeRoutesprocessor, the session is not available and the controller requests are not tracked. This is useful for custom routes that you do not need to track, for example Web API routes.

  • Web API routes (i.e., routes registered with the System.Web.Http.HttpRouteCollectionExtensions.MapHttpRoute extension method) aren't affected by the Sitecore.Mvc.Pipelines.Loader.InitializeRoutes processor. This processor only modifies routes registered for MVC (i.e., routes registered with the System.Web.Mvc.RouteCollectionExtensions.MapRoute extension method). – Corey Smith Feb 6 '18 at 15:06
  • @CoreySmith Yes, but the placement affects tracking. It was more of an FYI than a requirement. – jammykam Feb 6 '18 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.