Error when try to run from virtual directory (IIS)

Feb 7, 2010 at 2:49 PM

Hello, here is the steps i did:

  1. Create new mvc 2 preview application with default content.
  2. Add reference to MvcSiteMap.Core
  3. Add provider info to web.config according to mvcmap sample
  4. Create simple site map:
    <?xml version="1.0" encoding="utf-8" ?>
    <siteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-1.0" enableLocalization="false">
      <mvcSiteMapNode title="Главная" controller="Home" action="Index">
          <mvcSiteMapNode title="About" controller="Home" action="About"/>
      </mvcSiteMapNode>
    </siteMap>
    
  5. Publis app to some folder and create new virtual directory "test" inside default root site in IIS7 with physical path to folder i've created
  6. Run app an got error:

The controller for path '/test/' was not found or does not implement IController.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Web.HttpException: The controller for path '/test/' was not found or does not implement IController.

Source Error: 

Line 1128:                    if (!controllerCache.ContainsKey(cacheKey))
Line 1129:                    {
Line 1130:                        IController controller = ControllerBuilder.Current.GetControllerFactory().CreateController(context, controllerName);
Line 1131:                        controllerCache.Add(cacheKey, controller);
Line 1132:


Source File: D:\Projects\domopolis\Source\UI\ExternalControls\MvcSiteMap.Core\MvcSiteMapProvider.cs    Line: 1130 

Stack Trace: 

[HttpException (0x80004005): The controller for path '/test/' was not found or does not implement IController.]
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +487163
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +75
   MvcSiteMap.Core.MvcSiteMapProvider.GetController(RequestContext context, String controllerName, String areaName) in D:\Projects\domopolis\Source\UI\ExternalControls\MvcSiteMap.Core\MvcSiteMapProvider.cs:1130
   MvcSiteMap.Core.DefaultMvcSiteMapAclModule.IsAccessibleToUser(MvcSiteMapProvider provider, HttpContext context, SiteMapNode node) in D:\Projects\domopolis\Source\UI\ExternalControls\MvcSiteMap.Core\DefaultMvcSiteMapAclModule.cs:93
   MvcSiteMap.Core.MvcSiteMapProvider.IsAccessibleToUser(HttpContext context, SiteMapNode node) in D:\Projects\domopolis\Source\UI\ExternalControls\MvcSiteMap.Core\MvcSiteMapProvider.cs:557
   System.Web.SiteMapProvider.get_RootNode() +42
   MvcSiteMap.Core.MvcSiteMapProvider.get_RootNode() in D:\Projects\domopolis\Source\UI\ExternalControls\MvcSiteMap.Core\MvcSiteMapProvider.cs:133
   MvcSiteMap.Core.Helpers.MenuHelper.Menu(HtmlHelper helper, String providerName, Boolean showStartingNode, Int32 startingNodeLevel, Boolean startFromCurrentNode, String selectedMenuItemCssClass, Int32 maxLevels, Object menuHtmlAttributes, Int32 pinnedNodeLevel) in D:\Projects\domopolis\Source\UI\ExternalControls\MvcSiteMap.Core\Helpers\MenuHelper.cs:204
   MvcSiteMap.Core.Helpers.MenuHelper.Menu(HtmlHelper helper, String providerName, Boolean showStartingNode, Boolean startFromCurrentNode, String selectedMenuItemCssClass, Int32 maxLevels, Object menuHtmlAttributes) in D:\Projects\domopolis\Source\UI\ExternalControls\MvcSiteMap.Core\Helpers\MenuHelper.cs:93
   MvcSiteMap.Core.Helpers.MenuHelper.Menu(HtmlHelper helper, Boolean showStartingNode, Boolean startFromCurrentNode, String selectedMenuItemCssClass, Object menuHtmlAttributes) in D:\Projects\domopolis\Source\UI\ExternalControls\MvcSiteMap.Core\Helpers\MenuHelper.cs:51
   MvcSiteMap.Core.Helpers.MenuHelper.Menu(HtmlHelper helper, String selectedMenuItemCssClass, Object menuHtmlAttributes) in D:\Projects\domopolis\Source\UI\ExternalControls\MvcSiteMap.Core\Helpers\MenuHelper.cs:37
   ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in d:\Projects\tst\MvcApplication1\Views\Shared\Site.Master:23
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +115
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +240
   System.Web.UI.Page.Render(HtmlTextWriter writer) +38
   System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +89
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4240

I am trying to resolve the reason, but maybe you can make it faster. Thanks.

Alexey

Feb 9, 2010 at 4:10 PM

I have the same problem ! the sitemap did not found the start controlername. At the first step controlername allways "/" . It works if i set the string from "/" to "Home"

Feb 19, 2010 at 6:38 PM

Yes! Haha! This has been bugging me for weeks and I finally just found this page! Some semblance of sanity can finally return to my life! I fought with the routing on my site on and off trying to figure this out for so long... I could have saved myself some time by actually reading the stack trace... duh.

I can confirm that is an issue. Note that without the slash, this WILL work, but MvcSitemapProvider doesn't seem to take the application root into account with the slash:

http://localhost/test - works

http://localhost/test/ - doesn't work (Thinks that "test" is a controller name)

Apr 16, 2010 at 10:24 PM

You're not the only ones having this issue.

I'm utilizing MVC for a couple of sites located in a corporate intranet.  Each of these sites are required due to company policies to be run under virtual directories of a particular domain.

 

I'm getting the same exact error regarding the virtual directories...  however everything runs fine when doing local development under Cassini.

Apr 26, 2010 at 11:48 AM
if someone needs a quick (hack) fix, here's my solution:

I did some changes to the DefaultMvcSiteMapAclModule.cs (starts around line 63):

   // Find current request context
   HttpContextBase httpContext = new HttpContextWrapper(context);
            
   // *** change 1: remember the original request path
   string originalPath = httpContext.Request.Path;
   // *** change 2: rewrite with our requested url
   httpContext.RewritePath(node.Url); 
            
   var routes = RouteTable.Routes.GetRouteData(httpContext);

   // *** change 3: reset the http context to the original request path
   httpContext.RewritePath(originalPath.ToString()); 
            

   RequestContext requestContext = null;
this changes are based on a discussion on so -> http://stackoverflow.com/questions/2066615/manually-instantiate-a-controller-instance-from-an-arbitrary-urlhttp://stackoverflow.com/questions/2066615/manually-instantiate-a-controller-instance-from-an-arbitrary-url
hope it helps.
Apr 26, 2010 at 2:43 PM

Good suggestion, thanks!

May 20, 2010 at 2:30 PM

Hello, I have experienced same issue running MVC application on my desktop (Windows 7) under virtual directory.

I made some tests and found 2 problems

1. The GetRouteData(httpContext) doesn't return data for node.Url but it returns data for original path

2. In MvcSiteMapProvider.cs / GetController() method. Sometime the CreateController returns null, and the controllerCache store a null.

Maybe we could protect the cache with

if (null != controller) {
   controllerCache.Add(cacheKey, controller);
}

 

Jun 24, 2010 at 5:10 PM

Has a fix been implemented for 2.0?

Jun 30, 2010 at 1:09 PM

Has been tested under IIS7, integrated pipeline, in a virtual directory (i.e. http://localhost/MvcMusicStore/Home/SiteMap), works smoothly.