【问题标题】:MVC: How to route /sitemap.xml to an ActionResult?MVC:如何将 /sitemap.xml 路由到 ActionResult?
【发布时间】:2010-01-05 14:18:11
【问题描述】:

我有一个覆盖 ActionResult 的 SitemapActionResult,并在http://www.sprelle.no/Home/SiteMap 被点击时提供一个 SEO sitemap.xml。到目前为止一切顺利。

不过,我希望在 Google 访问 /sitemap.xml 时提供 sitemap.xml。为此,我需要一条能看到“sitemap.xml”并指向/Home/Sitemap 的路线。

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

【问题讨论】:

    标签: asp.net-mvc seo sitemap sitemap.xml


    【解决方案1】:

    添加地图:

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

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

    【讨论】:

    • 我实际上在今天早些时候尝试过这个,但无法让它工作,因为我在默认路由之后添加了路由。它需要插入之前 默认路由才能工作。谢谢。
    • 还记得在 system.webServer 中为您的模块配置添加 runAllManagedModulesForAllRequests="true",否则它将尝试使用静态文件处理程序并返回 404
    • @RaulVejar 谢谢!我在网上搜索了一个多小时,你是第一个提到模块的人。它解决了我的问题。
    • runAllManagedModulesForAllRequest 会影响您的性能。也许您只能在 system.webServer.modules 中为 sitemap.xml 添加一个 enry:
    • @RaduD 它应该进入 system.webServer.handlers,而不是 .modules。
    【解决方案2】:

    你可以用这个。

    步骤 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="*" 有一个包罗万象的StaticFile 映射,它指向StaticFileModule,DefaultDocumentModule,DirectoryListingModule。如果您什么都不做,那将处理您的 .html 请求。所以第一步是在你的 web.config 中添加一个处理程序,它将*.html 请求指向TransferRequestHandlerTransferRequestHandler 是处理您习惯于在 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" />
    

    请注意,如果您愿意,可以使路径更具体。例如,如果你只想拦截一个特定的请求,你可以使用 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 错误(递归溢出),不得不向 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 }
                );
        }
    

    就是这样。

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

    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");
    }
    

    【讨论】:

    • 虽然这个答案可能是正确的,但最好在此处包含相关代码。如果网站移动或被删除,仅链接的答案可能会变得不正确。
    【解决方案3】:

    要让它发挥作用,你需要做两件事:

    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" }
    );
    

    【讨论】:

    • 这个答案也很有用,但是在底部
    猜你喜欢
    • 2014-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    相关资源
    最近更新 更多