我有一个带有无扩展名URL的ASP.NET MVC 4应用程序(使用.NET framework 4.5)。该站点包含一些静态文件,但所有无扩展请求应进入MVC路由。
这一切都适用于以下请求:
但是如果我向/ 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中的modules元素中(我不是真的想这样做,但它无论如何都没有帮助。)
编辑 - 如果它有用,这里是路由:
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 :(得分: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部分选择模块,然后从操作选项卡中查看有序列表。将UrlRoutingModule移到DirectoryListingModule上面。
作为旁注,根据您的评论,我了解您只有一个控制器,只需一个操作。除了使用IgnoreRoute
定义的静态资源外,该操作还将为所有请求提供服务。这不是推荐的设置,因为您失去了MVC架构的所有好处。此外,您会发现您的Page操作会迅速增长,以包含越来越多的案例。这正是路由和控制器旨在解决的问题。
如果你认为单一的catch-all方法对你来说是最好的解决方案,那么你真的不需要MVC,你最好使用Web API,它的请求开销要小得多。
答案 1 :(得分:0)
编辑:我最初认为有必要删除DirectoryListingModule,但事实并非如此,我的自定义HttpModule重写在此之前启动,因此可以保留。
我用来解决此问题的解决方法是向自定义HttpModule添加一些逻辑,该HttpModule正在进行一些请求处理。在这里,我检测请求是否对应于我的一个本地化的根(/ fr / / es / etc.),如果是,则将url重写为默认页面/ fr / index,路由正常工作。< / p>
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