Sitecore MVC Exception on Content Delivery servers

Search for a command to run...

No comments yet. Be the first to comment.
Polly is great library for easily configuring different kinds of policies around code execution, be it retry, circuit breaker, caching or lots of other things. It's probably most often used around HTTP requests. If you haven't heard about it you defi...

This is part 2 of my series on unit testing in .NET (C#) and will be about my conventions regarding naming unit tests, how to structure them and which parts to test. And lastly I will help you increase readability of assertions and potential error me...

I feel like unit testing is very important and very beneficial in a lot of ways. It helps with not breaking existing functionality and thereby also making you more confident in changing code without fear of breaking important stuff. Often it also mak...

I've been working with Swagger through NSwag a lot recently and also needed to get it to work when hidden behind a reverse proxy - i.e. another service forwarding a request to the service exposing the Swagger UI. Some of the issues I've had along the...

The other day I was writing a unit test to verify what was supposed to happen when a Task would throw an exception when awaited. It wasn't as straight forward as I first assumed, but I quickly found this Stack Overflow post that helped me: https://st...

If you use MVC and follow Sitecore's guidelines with regards to which config files should be enabled/disabled on CD servers you might run into this exception:
InvalidOperationException: No route in the route table matches the supplied values.
This can happen when you have deleted/disabled the Sitecore.Speak.Mvc.config, which Sitecore recommends you do on Content Deliver servers, and use the default MVC helper methods @Html.Action and @Html.RenderAction in your renderings.
For some reason those methods requires a route containing the pattern {controller}/{action} to work. These are part of the default route in a standard MVC project, but usually not in a Sitecore project.
But then why does it work until we delete/disable Sitecore.Speak.Mvc.config?
Because that config files adds a processor to the initialize pipeline.
<initialize>
<processor type="Sitecore.Mvc.Pipelines.Initialize.InitializeCommandRoute, Sitecore.Speak.Client" patch:before="processor[@type='Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc']"/>
</initialize>
This processor registers the following routes:
protected virtual void RegisterRoutes(RouteCollection routes, PipelineArgs args)
{
string commandRoutePrefix = SpeakSettings.Mvc.CommandRoutePrefix;
routes.MapRoute("Sitecore.Speak.Commands", commandRoutePrefix + "{controller}/{action}");
routes.MapRoute("Sitecore.Speak", "sitecore/shell/api/sitecore/{controller}/{action}");
}
So when you delete/disable this config file, those routes do no longer get registered.
It's pretty simple to fix. You just have to add a route containing the {controller}/{action} pattern in your own processor in the initialize pipeline.
// Something like this
RouteTable.Routes.MapRoute(
"Bogus-Required-Route",
"bogus-required-route/{controller}/{action}",
);
I'm not sure if the route would overwrite Sitecore's route handling, so to be sure I would use a distinct path for the route that you are sure to never match a page URL for your site.
If you want to prevent the action method from being invoked as a result of a user request you can add the [ChildActionOnly] attribute to it.
If for some reason, like me, you can never find the download link for the Config Enable-Disable spreadsheet, then you can find them on this page.