MVC:如何将/sitemap.xml路由到ActionResult?

Haa*_*onL 13 sitemap asp.net-mvc seo sitemap.xml

我有一个SitemapActionResult覆盖了ActionResult,并在点击http://www.sprelle.no/Home/SiteMap时提供了一个SEO sitemap.xml .到现在为止还挺好.

不过,我想要的是在Google访问/sitemap.xml时提供sitemap.xml.为了实现这一点,我需要一个看到"sitemap.xml"并指向/ Home/Sitemap的路线.

如何创建此映射(在Routes表中)?

ben*_*wey 19

添加地图:

routes.MapRoute(
            "Sitemap",
            "sitemap.xml",
            new { controller = "Home", action = "SiteMap" }
            );
Run Code Online (Sandbox Code Playgroud)

请注意,路由,控制器和操作选项是硬编码的.

  • runAllManagedModulesForAllRequest将影响您的性能.也许你只能在system.webServer.modules里面为sitemap.xml添加一个enry:<add name ="ManagedFileWithExtension"path ="sitemap.xml"verb ="GET"type ="System.Web.Handlers.TransferRequestHandler"preCondition = "integratedMode,runtimeVersionv4.0"/> (18认同)
  • 还记得为system.webServer中的模块配置添加runAllManagedModulesForAllRequests ="true",否则它将尝试使用静态文件处理程序,它将返回404 (13认同)
  • 我今天早些时候尝试过这个,但是无法让它工作,因为我添加了路由_after_默认路由.它需要插入_before_默认路由才能工作.谢谢. (8认同)
  • @RaduD它应该放在system.webServer.handlers中,而不是.modules. (7认同)

Run*_*sen 8

要使其正常工作,您需要做两件事:

  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>
Run Code Online (Sandbox Code Playgroud)
  1. 在您的 MVC 应用程序中放置一条路由,将该请求与 ActionResult 匹配(确保将其放置在默认路由之前):
routes.MapRoute(
    name: "Sitemap",
    url: "sitemap.xml",
    defaults: new { controller = "YourControllerName", action = "YourActionName" }
);
Run Code Online (Sandbox Code Playgroud)


小智 7

你可以用它.

步骤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中加载它.

如果你滚动到底部,你会看到有一个path="*" verb="*"指向静态文件的静态映射StaticFileModule,DefaultDocumentModule,DirectoryListingModule.如果你什么都不做的话,这就是你的.html请求.所以第一步是在web.config中添加一个处理程序,它将*.html请求指向TransferRequestHandler.TransferRequestHandler是处理你曾经在MVC路线中看到的无扩展名URL的处理程序,例如/store/details/5.

添加处理程序映射非常简单 - 只需打开web.config并将其添加到<system.webServer/handlers>节点即可.

<add name="HtmlFileHandler" path="*.html" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
Run Code Online (Sandbox Code Playgroud)

请注意,如果您愿意,可以使路径更具体.例如,如果您只想拦截一个特定请求,则可以使用path ="sample.html"

步骤2.配置路由

接下来,您将需要一条新路线.打开App_Start/RouteConfig.csRegisterRoutes打电话.我的完整RegisterRoutes看起来像这样:

  routes.MapRoute(
       name: "XMLPath",
       url: "sitemapindex.xml",
       defaults: new { controller = "Home", action = "Html", page = UrlParameter.Optional }
   );
Run Code Online (Sandbox Code Playgroud)

步骤3.路由现有文件

这几乎涵盖了它,但还有一件事需要处理 - 覆盖与现有文件匹配的请求.如果您有一个名为myfile.html的实际文件,则路由系统将不允许您的路由运行.我忘记了这一点,最终出现了HTTP 500错误(递归溢出),不得不向Eilon Lipton寻求帮助.

无论如何,这很容易修复 - 只需在路线注册中添加routes.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 }
            );
    }
Run Code Online (Sandbox Code Playgroud)

而已.

我通过添加此控制器操作进行测试:

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");
}
Run Code Online (Sandbox Code Playgroud)