ASP.NET MVC 3: RouteExistingFiles = true, похоже, не имеет эффекта

Я пытаюсь понять, как работает RouteExistingFiles. Поэтому я создал новый интернет-проект MVC 3 (MVC 4 ведет себя одинаково) и поместил файл HTMLPage.html в папку Content моего проекта. Теперь я перешел в файл Global.Asax и отредактировал функцию RegisterRoutes, чтобы он выглядел так:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.RouteExistingFiles = true; //Look for routes before looking if a static file exists

    routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new {controller = "Home", action = "Index", id = UrlParameter.Optional} // Parameter defaults
            );
    }

Теперь он должен дать мне ошибку, когда я запрашиваю localhost: XXXX/Content/HTMLPage.html, так как нет контроллера контента и запрос определенно попадает в шаблон по умолчанию. Но вместо этого я вижу свой HTMLPage. Что я здесь делаю неправильно?

Обновление: Думаю, мне придется сдаться. Даже если я добавлю такой маршрут, как этот:

routes.MapRoute("", "Content/{*anything}", new {controller = "Home", action = "Index"});

он все еще показывает мне содержимое HTMLPage. Когда я запрашиваю URL-адрес, например ~/Content/HTMLPage, я получаю страницу индекса, как ожидалось, но когда я добавляю расширение файла, например .html или .txt, отображается содержимое (или ошибка 404, если файл не существует), Если кто-нибудь может это проверить в VS2012, пожалуйста, дайте мне знать, какой результат вы получаете. Спасибо.

Ответ 1

Чтобы включить маршрутизацию для статических файлов, вы должны выполнить следующие шаги.

В RouteConfig.cs включить маршрутизацию для существующих файлов

routes.RouteExistingFiles = true;

Добавьте маршрут для вашего пути (убедитесь, что специализированный путь находится выше общих путей)

routes.MapRoute(
            name: "staticFileRoute",
            url: "Public/{file}/",
            defaults: new { controller = "Home", action = "SomeAction" }
        );

Затем настройте свое приложение, чтобы запрос на статические файлы обрабатывался с помощью "TransferRequestHandler". В Webconfig в разделе system.webServer > обработчики добавляют следующую запись.

<add name="MyCustomUrlHandler2" path="Public/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

Значение "путь" может быть более общим или конкретным в зависимости от вашего требования. Но я предпочитаю, чтобы он всегда был очень специфичным по одной необходимости. Сохранение его очень общего будет блокировать работу других ресурсов сайта, таких как .js или css файлы. Например, если выше указано как path = "*", тогда запрос даже для css (внутри папки содержимого), который отвечает за то, как будет выглядеть ваша страница, также окажется в вашем действии Controller. Что-то, что вам не понравится.

Ответ 2

RouteExistingFiles не позволяет просматривать файлы, если для них нет маршрута, он просто проверяет маршруты, прежде чем проверять, существует ли файл. Если нет соответствующего маршрута, он будет продолжать проверять, есть ли соответствующий файл.

Ответ 3

Visual Studio 2012 использует IIS Express. Вы должны сообщить IIS не перехватывать запросы на дисковые файлы, прежде чем они будут переданы в систему маршрутизации MVC. Вам нужно установить атрибут preCondition в пустую строку в файле конфигурации:

<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" 
     preCondition="" />

В Win7/8 вы можете найти файл конфигурации по этому пути: %userprofile%\Documents\IISExpress\config\applicationhost.config