2014-04-23 41 views
10

我有一個ASP.NET MVC 4應用程序(使用.NET框架4.5)與擴展名的URL。該網站包含一些靜態文件,但所有無擴展請求應該進入MVC路由。如何將對磁盤上存在的目錄的請求路由到ASP.NET MVC?

這一切工作正常,就像請求:

  • /
  • /新聞
  • /FR /新聞

但是如果我做了/ FR我得到錯誤的請求:

HTTP Error 403.14 - Forbidden, 
The Web server is configured to not list the contents of this directory. 

我明白,這是因爲實際上在磁盤上存在一個/ fr目錄,但是我仍然想將這個請求映射到我的MVC應用程序。它不是刪除fr目錄的選項,因爲它包含一些靜態文件。

這可能嗎?我曾嘗試將runAllManagedModulesForAllRequests="true"添加到system.webServer中的模塊元素中(我並不真的想要這樣做,但它無濟於事)。

編輯 - 在情況下,它是有用的,這裏是路由:

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
     routes.IgnoreRoute("cid/{*pathInfo}"); 
     routes.MapRoute(
      "Page", 
      "{*PageId}", 
      new { controller = "Page", action = "Page" }, // Parameter defaults 
      new { pageId = @"^(.*)?$" } // Parameter constraints 
     ); 
     routes.MapRoute(
      name: "Default", 
      url: "{controller}/{action}/{id}", 
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ); 
    } 
+0

我添加了路由,雖然我不確定這是否相關,因爲MVC路由從不會爲/ fr請求啓動。我很確定這是由於DirectoryListingModule選取它,但我無法從圖片中得到它(如在http://stackoverflow.com/questions/21842206/how-to-disable-or- reprioritize-iis-directorylistingmodule-under-mvc-module) – Will

+0

看看這裏[http://stackoverflow.com/a/17336588/3383479](http://stackoverflow.com/a/17336588/3383479) –

+0

不確定如何幫助,如上所述我不能刪除/ fr目錄 – Will

回答

5

防止訪問本地文件夾和文件的最簡單的方法是設置RouteCollection.RouteExistingFiles標誌讓ASP.NET處理的URL目標物理文件。因此,改變你的路徑登記到:

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
    routes.IgnoreRoute("cid/{*pathInfo}"); 

    routes.RouteExistingFiles = true; 
    routes.MapRoute(
     "Page", 
     "{*PageId}", 
     new { controller = "Page", action = "Page" }, // Parameter defaults 
     new { pageId = @"^(.*)?$" } // Parameter constraints 
    ); 
} 

"Default"路線並不需要爲"Page"真的是一個包羅萬象的情況。

另一種方法是更改​​IIS配置,使ASP.NET MVC路由的優先級高於IIS目錄列表。在IIS7中,到達您的網站,從IIS部分選擇Modules,然後從Actions選項卡查看Ordered List。將UrlRoutingModule移動到DirectoryListingModule上方。


作爲一個側面說明,從您的意見,我明白,你有一個動作一個控制器。除了使用IgnoreRoute定義的靜態資源之外,該操作將處理所有請求。這不是推薦的設置,因爲您放棄了MVC體系結構的所有好處。此外,你會發現你的Page行動將會迅速增長,以包含越來越多的案例。這正是路由和控制器設計要解決的問題。

如果你認爲單一的catch-all方法對你來說是最好的解決方案,那麼你並不需要MVC,而使用Web API的請求開銷要小得多。

+0

我希望避免通過MVC路由推送物理文件的請求,因爲我無法想象這不會對我的靜態影響有任何性能影響。 – Will

+0

感謝您對MVC架構的額外建議,不過別擔心 - 它是一個「合適」的MVC架構!應用程序連接到CMS,所以當請求進入時,我們首先將請求url映射到CMS中的頁面對象,該頁面對象定義了一組要觸發的子動作(使用默認路由和正常的MVC使用一堆控制器,動作和視圖) – Will

+0

@Will毫無疑問,路由會對性能產生影響,但您認爲它可能會更小。儘可能多的請求處理,ASP.NET嘗試推送到IIS,並且IIS處理程序在緩存方面很安靜。因此,如果您的設置是在IIS 7 +上託管的ASP.NET 4.0 +,那麼我不會過多擔心性能。在這裏看看更多的細節:http://blogs.msdn.com/b/tmarq/archive/2010/04/01/asp-net-4-0-enables-routing-of-extensionless-urls-without-影響靜態requests.aspx –

0

編輯:我最初認爲這是必要拆除DirectoryListingModule,但這種情況並非如此,我的自定義的HttpModule改寫踢在此之前,因此它可以在留

解決方法我。用於解決這個問題的方法是向正在做一些請求處理的自定義HttpModule添加一些邏輯。在這裏,我檢測請求是否與我的本地化之一(/ fr// es /等)相對應,如果是,則將url重寫爲缺省頁面/ fr/index,路由正常工作。

private void BeginRequest(object sender, EventArgs e) 
{ 
    HttpApplication application = (HttpApplication)sender; 
    HttpContext context = application.Context; 
    var url = context.Request.Url.AbsolutePath; 
    if (IsLocalizationRoot(url)) 
    { 
     context.RewritePath(url + GetDefaultPageName()); 
    } 
} 

如果你有興趣在如何卸下DirectoryListingModule(如上文提到的,這是沒有必要的,但它反正有用的信息):

由於StaticFileHandler引用它,你需要將其刪除,並刪除和你的web.config重新添加StaticFileHandler(不DirectoryListingModule):

<system.webServer> 
    <handlers> 
     <remove name="StaticFile"/> 
     <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule" 
      resourceType="Either" requireAccess="Read" /> 
    </handlers> 
    <modules> 
     <remove name="DirectoryListingModule"/> 
    </modules> 
</system.webServer> 

這可能會導致一個HTTP 500錯誤,由於鎖定衝突。你需要解鎖在IIS的applicationHost.config:

打開命令提示符(以管理員身份運行),然後轉到C:\ WINDOWS \ SYSTEM32 \ INETSRV

appcmd set module DirectoryListingModule /lockItem:false 
+0

儘管這有效 - 它感覺像是一種解決方法,所以我想知道是否有純粹的配置解決方案,它不涉及HTTP模塊,或通過MVC路由靜態請求... – Will

+0

它也不是一個通用的解決方案到現有目錄未被路由的問題 - 儘管它適用於我的用例 – Will

相關問題