2014-02-18 33 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

感謝您的建議。不幸的是,我們的項目比「地區允許」(單層)的結構更深。我們可以通過項目/區域/文件夾開始分解,但與簡單的文件夾結構相比,這會使我們的體系結構不必要地複雜化。 –