ASP.NET 頁面雙向靜態化


在上一篇博文ASP.NET 路由實現頁面靜態化中我已經詳細介紹並實現了.html頁面到.aspx頁面的映射,當然這屬於偽靜態,而且是單向的。

現在我們來實現第2點,當用戶請求Default.aspx頁面時,自動重定向到Index.html頁面。甚至當用戶請求某些.aspx頁面時,自動跳轉到與之對應的.html頁面。

按照這個邏輯,必然會造成循環請求,不斷地產生子請求,請求流程如下圖:

image

而我們預期的結果應該如下圖,實際只請求兩次。

image

用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的權限太高了。

果然,運行之后,出現下面的錯誤畫面:

SNAGHTML9af826

還是web.config的配置問題。在<webserver>節點下添加下面一行配置:

<validation validateIntegratedModeConfiguration="false"/>

這一行配置並不會真正影響web應用程序的安全性,它只是用於關閉有些配置將不會被使用的警告。

That’s end, have fun.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM