asp.net-mvcmvcsitemapprovidersitemapprovider

MVCSitemap Issue


I am facing a strange issue with MVC Sitemap. At present I had maximum of of 3 levels of sitemap link which may change in future. The problem is the middle level sitemap link is not working (clicking on the link throwing error - Http 403.1 Forbidden) when I am at the next level but the base level is working. It has found that URL is not proper, like the Area and Contoller name is only popping up the action name missed out.

EG: Home>Company>Add

When on Add screen (final level), - clicking on Home redirects to localhost:xxxx/Home/index and working fine.

and results in following error,

localhost:xxxx/Company/Company/

HTTP Error 403.14 - Forbidden The Web server is configured to not list the contents of this directory. Most likely causes: •A default document is not configured for the requested URL, and directory browsing is not enabled on the server.

The MVC.Sitemap details is as follows,

<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0"
    xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0 MvcSiteMapSchema.xsd">

<mvcSiteMapNode key="Home" title="Home" controller="Home" action="Index">
<mvcSiteMapNode key="Company" title="Company" area="Company" controller="Company" action="Index">
  <mvcSiteMapNode key="CompanyAdd" title="Add Company" area="Company" controller="Company" action="Add" />
</mvcSiteMapNode>
</mvcSiteMapNode>

</mvcSiteMap>

Solution

  • Whenever you get an error that says "The Web server is configured to not list the contents of this directory", it usually means that there is a physical directory at the same location as the URL, which is taking precedence over it. In other words, there is already a folder at the location <website_root_directory>\Company\Company\ and that takes precedence over a call to a controller with the same URL.

    The other issue you are having is due to the way you have set up your routing for the Company area. If you have an optional action name, and the configured value for the action name is the same as the optional value, it will be left off when the URL is generated.

    public class CompanyAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "Company";
            }
        }
    
        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "Company_default",
                "Company/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional },
                new string[] { "MyRootNamespace.Areas.Company.Controllers" }
            );
        }
    }
    

    This will generate the URL /Company/Company if the action name is "Index" and controller name is "Company".

    If you make the action not optional, then it will work like you expect.

    public class CompanyAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "Company";
            }
        }
    
        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "Company_default",
                "Company/{controller}/{action}/{id}",
                // Action was removed as an optional parameter
                new { id = UrlParameter.Optional },
                new string[] { "MyRootNamespace.Areas.Company.Controllers" }
            );
        }
    }
    

    Since the action name is required, the URL generated will be /Company/Company/Index if the action name is "Index" and controller name is "Company".