7

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.

3
  • 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. Commented Feb 6, 2018 at 4:55
  • Registering it after that line did not work
    – Ben Lipson
    Commented Feb 6, 2018 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. Commented Feb 6, 2018 at 14:26

4 Answers 4

16

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.

4
  • 2
    This was an issue for me in 9.2 as well - you're a lifesaver!
    – Hos
    Commented Jan 17, 2020 at 19:17
  • 1
    Thank you, this was the source of my issue too
    – NJH
    Commented Feb 27, 2020 at 7:38
  • 1
    Just encountered this today with JSS Dictionary Service. Clearing the controller type cache solved it. Thanks!
    – Adam Weber
    Commented Mar 25, 2020 at 23:14
  • Just encountered this issue too - thanks for sharing!
    – Kasaku
    Commented Apr 21, 2020 at 22:17
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.

2
  • 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). Commented Feb 6, 2018 at 15:06
  • @CoreySmith Yes, but the placement affects tracking. It was more of an FYI than a requirement.
    – jammykam
    Commented Feb 6, 2018 at 15:17
1

Deleting the controller type cache is worked for me . You must delete

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\xxxxx\xxxxx\UserCache\MS-ApiControllerTypeCache.xml

0

Go to the location C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root and find withe the file name "MS-ApiControllerTypeCache.xml" and C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root

Delete all files named MS-ApiControllerTypeCache.xml from the root folder.

For my case, the issue ought to be addressed this way

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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