我有一个覆盖 ActionResult 的 SitemapActionResult,并在点击http://www.sprelle.no/Home/SiteMap时提供一个 SEO sitemap.xml 。到现在为止还挺好。
不过,我想要的是在 Google 访问 /sitemap.xml 时提供 sitemap.xml。为此,我需要一条能看到“sitemap.xml”并指向/Home/Sitemap 的路线。
如何创建此映射(在 Routes 表中)?
我有一个覆盖 ActionResult 的 SitemapActionResult,并在点击http://www.sprelle.no/Home/SiteMap时提供一个 SEO sitemap.xml 。到现在为止还挺好。
不过,我想要的是在 Google 访问 /sitemap.xml 时提供 sitemap.xml。为此,我需要一条能看到“sitemap.xml”并指向/Home/Sitemap 的路线。
如何创建此映射(在 Routes 表中)?
添加地图:
routes.MapRoute(
"Sitemap",
"sitemap.xml",
new { controller = "Home", action = "SiteMap" }
);
请注意,路由、控制器和操作选项是硬编码的。
你可以用这个。
步骤 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
是处理您习惯于在 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");
}
要让它工作,你需要做两件事:
<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>
routes.MapRoute(
name: "Sitemap",
url: "sitemap.xml",
defaults: new { controller = "YourControllerName", action = "YourActionName" }
);