2014-02-18 29 views
4

我使用MVC的文件夹结构,其中URL路径正好匹配的目录名称,例如:如何在MVC模块下禁用或重新设置IIS DirectoryListingModule的优先级?

<proj>\My\Cool\Thing\ThingController.cs 

需要通过此网址访问:

http://blahblah/My/Cool/Thing 

我有MVC路由工作但不幸的是,在依赖默认{action} & {id}时,IIS Express将请求路由到DirectoryListingModule,因为它直接匹配文件夹名称。目录列表被禁用,当然如此,而不是我得到:

The Web server is configured to not list the contents of this directory. 
Module  DirectoryListingModule 
Notification  ExecuteRequestHandler 
Handler StaticFile 

为了解决这个问题我已经尝试:

1. runAllManagedModulesForAllRequests = true 

<system.webServer> 
<modules runAllManagedModulesForAllRequests="true" > 
//Makes no difference 

2. Removing module 

<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true" > 
    <remove name="DirectoryListingModule"/> 
    // Won't let me as module is locked in IIS 
    </modules> 
</system.webServer> 

3. Removing lock & module 

// applicationhost.config 
<add name="DirectoryListingModule" lockItem="false" /> 

// web.config 
<remove name="DirectoryListingModule"/> 
// Causes startup error"Handler "StaticFile" has a bad module "DirectoryListingModule" in its module list" 


4. Removing lock & removing/readding module (to change order) - makes no difference 

// web.config 
<remove name="DirectoryListingModule"/> 
<add name="DirectoryListingModule"/> 

撕裂了我的头发。我怎样才能让IIS将它路由到我的MVC应用程序而不是DirectoryListingModue?最好是web.config中的解决方案,以便我们不需要重新配置生产中的IIS。

(一种解决方法是保持我的文件夹结构,但其存储的所有下/地区/ ...相反,只是为了打破文件夹路径& URL之间的匹配,这是一个可怕的黑客&不得已而为之。)

编辑添加路由映射

我正在创建相对于每个控制器的命名空间(名称空间始终匹配文件夹)的自定义路由。请注意,当前所有内容都放在“Modules”名称空间/文件夹下,以避免上述问题。

private static void RegisterAllControllers(RouteCollection routes) 
    { 
     const string controllerSuffix = "Controller"; 
     const string namespacePrefix = "My.Cool.Websire.UI.Modules."; 

     var controllerTypes = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsSubclassOf(typeof(Controller))).ToList(); 

     foreach (var controllerType in controllerTypes) 
     { 
      // Turn My.Cool.Website.UI.Modules.X.Y.Z.Abc.AbcController into a route for url /X/Y/Z/Abc/{action}/{id} 
      var fullNamespace = controllerType.Namespace ?? ""; 

      var relativeNamespace = fullNamespace.Substring(namespacePrefix.Length, fullNamespace.Length - namespacePrefix.Length); 

      var controllerName = 
       controllerType.Name.EndsWith(controllerSuffix) 
       ? controllerType.Name.Substring(0, controllerType.Name.Length - controllerSuffix.Length) 
       : controllerType.Name; 

      var url = relativeNamespace.Replace(".", "/") + "/{action}/{id}"; 

      var routeName = "Dedicated " + controllerName + " route"; 

      routes.MapRoute(routeName, url, new { controller = controllerName, action = "Index", id = UrlParameter.Optional }); 
     } 
    } 
+0

你可以添加你的路线映射吗?另外您如何发布/打包该网站?如果您正确发布站点,控制器的物理文件夹结构(即\ My \ Cool \ Thing \)应该不存在... –

+0

尽管对视图保留了文件夹结构,对吧?我已经发布了控制器映射。 –

+0

更正视图的文件夹结构,并在发布时保留任何其他内容文件夹(即图像,脚本等)。另一个问题,你有控制器名称重复吗?例如'X.Y.Z.Home.HomeController'和'A.B.C.Home.HomeController'? –

回答

2

我在这个阶段的解决方案是将一个/模块/文件夹下的Web用户界面项目的MVC内容:然后使用路由代码贴我可以通过URL访问此

My.Cool.Site.WebUI/Modules/Something/Blah/BlahController 
My.Cool.Site.WebUI/Modules/Something/Blah/Views/... 
My.Cool.Site.WebUI/Modules/Something/Blah/PartialViews/... 

http://.../Something/Blah/[action] 

因为这些文件在/模块/文件夹中,这打破了网址,并围绕我的问题得到的文件夹路径之间的匹配。

不是一个很好的解决方案,但做的工作。

0

我想如果你想分开你的控制器在文件夹中,所以他们不在“控制器”之下,你应该使用MVC提供的“区域”功能。它是为此目的而设计的。

+0

感谢您的建议。不幸的是,我们的项目比“地区允许”(单层)的结构更深。我们可以通过项目/区域/文件夹开始分解,但与简单的文件夹结构相比,这会使我们的体系结构不必要地复杂化。 –