Вы можете использовать это.
Шаг 1. Сопоставление расширения файла с TransferRequestHandler
В интегрированном режиме IIS 7 используются сопоставления обработчика HTTP, которые указывают комбинации пути / глагола на обработчик HTTP. Например, существует сопоставление обработчика по умолчанию, которое указывает path = "*. Axd" verb = "GET, HEAD, POST, DEBUG" на соответствующий модуль ISAPI для версии среды выполнения .NET, под которой работает сайт. Самый простой способ просмотреть обработчики по умолчанию в IIS Express - это запустить сайт в IIS Express, щелкнуть правой кнопкой мыши значок IIS Express на панели задач, выбрать «показать все приложения» и щелкнуть сайт. Ссылка applicationhost.config внизу связана, поэтому вы можете просто щелкнуть по ней, и она должна загрузиться в Visual Studio.
Если вы прокрутите вниз, вы увидите, что есть загадочное отображение StaticFile для path="*" verb="*"
, которое указывает на StaticFileModule,DefaultDocumentModule,DirectoryListingModule
. Вот что обработает ваш .html запрос, если вы ничего не сделаете. Поэтому первым шагом является добавление обработчика в ваш web.config, который будет направлять *.html
запросы на TransferRequestHandler
. TransferRequestHandler
- это обработчик, который заботится о URL без расширений, которые вы привыкли видеть в маршрутах MVC, например, /store/details/5
.
Добавить отображение обработчика действительно просто - просто откройте ваш web.config и добавьте его в узел <system.webServer/handlers>
.
<add name="HtmlFileHandler" path="*.html" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
Обратите внимание, что вы можете сделать путь более конкретным, если хотите. Например, если вы хотите перехватить только один конкретный запрос, вы можете использовать path = "sample.html"
Шаг 2. Настройка маршрута
Далее вам понадобится новый маршрут. Откройте App_Start/RouteConfig.cs
и позвоните на RegisterRoutes
. Моя полная RegisterRoutes
выглядит так:
routes.MapRoute(
name: "XMLPath",
url: "sitemapindex.xml",
defaults: new { controller = "Home", action = "Html", page = UrlParameter.Optional }
);
Шаг 3. Маршрутизация существующих файлов
Это почти покрывает это, но есть еще одна вещь, о которой нужно позаботиться - переопределение запросов, соответствующих существующему файлу. Если у вас есть файл myfile.html, система маршрутизации не позволит запустить ваш маршрут. Я забыл об этом, в результате возникла ошибка HTTP 500 (переполнение рекурсии), и мне пришлось обратиться за помощью к Эйлону Липтону.
В любом случае, это легко исправить - просто добавьте route.RouteExistingFiles = true для регистрации вашего маршрута. Мой завершенный вызов RegisterRoutes выглядит следующим образом:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.RouteExistingFiles = true;
routes.MapRoute(
name: "CrazyPants",
url: "{page}.html",
defaults: new { controller = "Home", action = "Html", page = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Вот и все.
Я проверил, добавив это действие контроллера:
public FileResult Html()
{
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
stringBuilder.AppendLine("<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">");
stringBuilder.AppendLine("<sitemap>");
stringBuilder.AppendLine("<loc>http://sprint-newhomes.move.com/sitemaps/sitemap_01.xml</loc>");
stringBuilder.AppendLine("<lastmod>" + DateTime.Now.ToString("MMMM-dd-yyyy HH:mm:ss tt") + "</lastmod>");
stringBuilder.AppendLine("</sitemap>");
stringBuilder.AppendLine("<sitemap>");
stringBuilder.AppendLine("<loc>http://sprint-newhomes.move.com/sitemaps/sitemap_02.xml</loc>");
stringBuilder.AppendLine("<lastmod>" + DateTime.Now.ToString("MMMM-dd-yyyy HH:mm:ss tt") + "</lastmod>");
stringBuilder.AppendLine("</sitemap>");
stringBuilder.AppendLine("</sitemapindex>");
var ms = new MemoryStream(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
Response.AppendHeader("Content-Disposition", "inline;filename=sitemapindex.xml");
return new FileStreamResult(ms, "text/xml");
}