在上一篇博文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.