ASP.NET 页面双向静态化
在上一篇博文ASP.NET 路由实现页面静态化中我已经详细介绍并实现了.html页面到.aspx页面的映射,当然这属于伪静态,而且是单向的。
现在我们来实现第2点,当用户请求Default.aspx页面时,自动重定向到Index.html页面。甚至当用户请求某些.aspx页面时,自动跳转到与之对应的.html页面。
按照这个逻辑,必然会造成循环请求,不断地产生子请求,请求流程如下图:
而我们预期的结果应该如下图,实际只请求两次。
用301重定向可以解决该循环请求产生的问题。
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事件
如果你不太熟悉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.
本文链接: 文章作者:keepfool 文章出处:http://www.cnblogs.com/keepfool/ 如果您觉得阅读本文对您有帮助,请点一右下角的“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎看官们转载,转载之后请给出作者和原文连接。