Sitecore MVC and Duplicate Controller Names
Recently I started developing on a project that uses MVC in a multi-site environment. Since MVC is still fairly new to Sitecore there are a few details for us developers to experience and work out. We had created a controller which was referenced by its name in a Controller Rendering. This worked fine and everything pulled together as intended allowing the functionality of the controller to work inside our presentation layer.
However once we started our next site, we decided to branch off using similar functionality of our last controller but with enough differences that it justified a separate development path. With this process we kept the same controller name. Right away the first thing we noticed was a rather ugly error message:
Multiple types were found that match the controller named ControlX . This can happen if the route that services this request ( {*pathInfo} ) does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the MapRoute method that takes a namespaces parameter.
The request for ControlX has found the following matching controllers:
ProjectA.Controllers.ControlX
ProjectB.Controllers.ControlX
Initially we looked at the routes and modifying the Global.asax to support our customization. Unless there is something I missed about this approach the closest we could get was a controller standing independent of Sitecore. As in only what was in the controller was present on the page. None of the rest of the components that made up the presentation layer were rendered. Adding routes in general just trumps the whole Sitecore page rendering process. Taking this approach may be handy when you need to place something in the site that is not controlled by Sitecore, but in our scenario this was undesirable.
After some work with Sitecore support, it became very obvious what the solution is. Do not use controller names in control renderings, but instead use the fully qualified path to your controller. In our situation that meant that instead of ControllerX use the fully qualified path of ProjectA.Controllers.ControllerX, ProjectA . This will guarantee uniqueness with all your controller references going forward.