MVC: Как направить /sitemap.xml в ActionResult? - PullRequest
12 голосов
/ 05 января 2010

У меня есть SitemapActionResult, который переопределяет ActionResult и доставляет SEO sitemap.xml при нажатии http://www.sprelle.no/Home/SiteMap. Пока все хорошо.

Я хотел бы, однако, обслуживать sitemap.xml, когда Google посещает /sitemap.xml. Чтобы это работало, мне нужен маршрут, который видит "sitemap.xml" и направляет в /Home/Sitemap.

Как мне создать это отображение (в таблице маршрутов)?

Ответы [ 3 ]

18 голосов
/ 05 января 2010

Добавить карту для:

routes.MapRoute(
            "Sitemap",
            "sitemap.xml",
            new { controller = "Home", action = "SiteMap" }
            );

Обратите внимание, что параметры маршрута, контроллера и действий жестко заданы.

7 голосов
/ 19 мая 2015

Вы можете использовать это.

Шаг 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");
}
2 голосов
/ 10 декабря 2017

Чтобы заставить это работать, вам нужно сделать 2 вещи:

  1. Дайте IIS команду разрешить статический запрос файла " / sitemap.xml " на ваш контроллер. В противном случае IIS будет обходить ваше приложение и искать файл с таким именем. Добавьте следующую строку в ваш web.config:
<system.webServer>
    <handlers>

        <!-- add the following line -->
        <add name="SitemapXml" path="sitemap.xml" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>

    </handlers>
</system.webServer>
  1. Поместите маршрут в вашем приложении MVC, который соответствует этому запросу, к ActionResult (убедитесь, что вы поместили его до маршрута по умолчанию):
routes.MapRoute(
    name: "Sitemap",
    url: "sitemap.xml",
    defaults: new { controller = "YourControllerName", action = "YourActionName" }
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...