在上一篇博文ASP.NET 路由实现页面静态化中我已经详细介绍并实现了.html页面到.aspx页面的映射,当然这属于伪静态,而且是单向的。 现在我们来实现第2点,当用户请求Default.aspx页面时,自动重定向到Index.html页面。甚至当用户请求某些.aspx页面时,自动跳转到与之对应的.html页面。 按照这个逻辑,必然会造成循环请求,不断地产生子请求,请求流程如下图: 而我们预期的结果应该如下图,实际只请求两次。 用301重定向可以解决该循环请求产生的问题。 OK, let’s begin. 本文的Demo和Source是基于上一篇的,如果下面的一些文件或文件夹没有提及创建的,表示已经在上一篇文章中创建过。
本文已经同步至我的个人博客站点:积累吧|ASP.NET 页面双向静态化 源代码下载:Routing-Static-Page-Demo-V2 Demo(点击这些链接会自动跳转到对应的.html页): 1. 修改CustomRouteHandler类,添加RequestPath属性using System.Web; using System.Web.Compilation; using System.Web.Routing; using System.Web.UI; namespace Routing_Static_Page_Demo.WebHandler { public class CustomRouteHandler : IRouteHandler { /// <summary> /// 虚拟路径 /// </summary> public string VirtualPath { get; private set; } /// <summary> /// 请求路径 /// </summary> public string RequestPath { get { return VirtualPath.Substring(1); } } public CustomRouteHandler(string virtualPath) { this.VirtualPath = virtualPath; } /// <summary> /// 返回实际请求页 /// </summary> public IHttpHandler GetHttpHandler(RequestContext requestContext) { foreach (var urlParm in requestContext.RouteData.Values) { requestContext.HttpContext.Items[urlParm.Key] = urlParm.Value; } var page = BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(Page)) as IHttpHandler; return page; } } } RequestPath属性是从VirtualPath过来的,如果VirtualPath为~/default.aspx,那么对应的RequestPath则是/default.aspx 2. 在WebModule下创建CustomHttpModule.cs类using System; using System.Globalization; using System.Web; using System.Web.Routing; using Routing_Static_Page_Demo.WebHandler; namespace Routing_Static_Page_Demo.WebModule { public class CustomHttpModule : IHttpModule { private HttpApplication app; public void Init(HttpApplication context) { app = context; app.AuthorizeRequest += App_AuthorizeRequest; } public void App_AuthorizeRequest(object sender, EventArgs e) { HttpRequest req = app.Request; string path = req.Path; // 如果是.aspx页面 if (path.EndsWith(".aspx", true, CultureInfo.CurrentCulture)) { // routeUrl则用于存放对应的.html string routeUrl = string.Empty; // 遍历RouteTable,找到.aspx页面对应的.html foreach (Route route in RouteTable.Routes) { // 获取CustomRouteHandler var handler = (CustomRouteHandler) route.RouteHandler; // 获取CustomRouteHandler的RequestPath string requestPath = handler.RequestPath; if (requestPath.ToLower() == path.ToLower()) { routeUrl = route.Url; break; } } // 将.aspx页面永久重定向到对应的.html页面 app.Response.StatusCode = 301; app.Response.AddHeader("Location", "/" + routeUrl); app.Response.End(); } } public void Dispose() { } } } 如果你不太熟悉HttpApplication的事件,可以参照:MSDN HttpApplication事件 3. 修改web.config文件,添加HttpModule配置黄色标记的地方是添加的,其它配置不变。 <?xml version="1.0" encoding="UTF-8"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> <httpModules> <add name="CustomHttpModule" type="Routing_Static_Page_Demo.WebModule.CustomHttpModule, Routing_Static_Page_Demo" /> </httpModules> </system.web> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <remove name="UrlRoutingModule"/> <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <add name="CustomHttpModule" type="Routing_Static_Page_Demo.WebModule.CustomHttpModule" /> </modules> <handlers> <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> </handlers> </system.webServer> </configuration> 在VS自带的WebDev服务器中运行这个项目:在浏览器栏输入http://localhost:xxxx/Default.aspx,会自动跳转到http://localhost:xxxx/Index.html,运行默认路径http://loclhost:xxxx/也会自动跳转到http://localhost:xxxx/Index.html。 4. 在IIS中运行项目WebDev运行虽然通过了,IIS可不见得通过,毕竟WebDev的权限太高了。 果然,运行之后,出现下面的错误画面: 还是web.config的配置问题。在<webserver>节点下添加下面一行配置: <validation validateIntegratedModeConfiguration="false"/> 这一行配置并不会真正影响web应用程序的安全性,它只是用于关闭有些配置将不会被使用的警告。 That’s end, have fun. Always keep dream, keep thinking, keep moving, even if the road obstacles , the one more important thing is that always be a pig for you, that's keep fool. |