zoukankan      html  css  js  c++  java
  • ASP.NET 路由实现页面静态化(附在线Demo和Source)

    页面静态化最大的好处是利于SEO,即使是伪静态,搜索引擎也会觉得这是一个较为友好的Url。Url的友好也取决于其命名,为一篇描述古代文学的页面起名用ancient-literature.html当然比随便起的名字例如aa.html之流要友好。页面静态化并不代表你一定要用后缀名为.html或.htm的链接来显示你的页面,你完全可以不用任何后缀名(就像MVC一样),只要Url结构良好。

    实现静态化的三个目标:

    1. 实现页面静态化,页面中的链接都用.html来表示,但每个.html实际都映射了一个.aspx页面。

    例如:当用户请求index.html页面时,实际请求的是Default.aspx页面,index.html的物理路径在网站中并不存在。

    2. 实现请求.aspx页面时自动跳转到对应的静态映射页面。

    例如:当用户请求Default.aspx页面,自动跳重定向到index.html页面

    3. 自定义404页面的实现,当请求的路径既不在映射表中,也不在网站的虚拟路径中时,它将自动跳转到我预先设定好的404页面。

    实现以上要点,需要用到ASP.NET Url Routing、HttpHandler和HttpModule技术。

    这是一个小系列的文章,这一篇文章将详细解说并实现第1点。

    一、项目创建

    1. 创建一个ASP.NET Web Application项目

    SNAGHTMLf9ef62

    image

    2. 创建web.config文件

    ASP.NET Membership在这里使用不到,所以生成的web.config配置没有用处,删掉它并重新创建一个新的web.config文件

    <?xml version="1.0"?>
    <configuration>
    
        <system.web>
            <compilation debug="true" targetFramework="4.0" />
        </system.web>
    
    </configuration>
    
    

    3. 将网站添加到IIS6或IIS7中

    SNAGHTML1048e8d

    默认的ASP.NET Web Application已经为我们提供了不少页面,我就在下面的例子中将它们静态化吧。

    二、页面静态化实现

    1. 添加Routing引用

    由于这里需要用到ASP.NET的路由映射(从.NET 3.5开始诞生),所以需要在项目中添加System.Web.Routing引用。

    SNAGHTMLfc9503

    SNAGHTML1007756

    2. 添加WebHandler和WebModule文件夹

    这两个文件夹分别用于存放IHttpHandler和IHttpModule。

    3. 将所有.aspx后缀的超链接更改为.html

    Site.Master文件:

    <asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal">
        <Items>
            <asp:MenuItem NavigateUrl="~/Index.html" Text="Home"/>
            <asp:MenuItem NavigateUrl="~/About.html" Text="About"/>
        </Items>
    </asp:Menu>
    

    Account文件夹ChangePassword.aspx文件:

    <asp:ChangePassword ID="ChangeUserPassword" runat="server" CancelDestinationPageUrl="~/" EnableViewState="false" RenderOuterTable="false" 
             SuccessPageUrl="ChangePasswordSuccess.html">
    

    当然现在这三个静态链接都访问不到,因为它们的物理地址不存在。

    下面我们要做的就是:

    1) 请求Index.html时实际请求的是Default.aspx

    2) 请求About.html时实际请求的是About.aspx

    3) 请求Account/Login.html时实际请求的是Account/Login.aspx

    4. 添加自定义的IRouteHandler实现

    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; }
            
            public CustomRouteHandler(string virtualPath)
            {
                this.VirtualPath = virtualPath;
            }
    
            /// <summary>
            /// 返回实际请求页
            /// </summary>
            public IHttpHandler GetHttpHandler(RequestContext requestContext)
            {
                var page = BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(Page)) as IHttpHandler;
                return page;
            }
        }
    }

    5. 在Global.asax文件中注册路由

    先来个简单的实现:

    using System;
    using System.IO;
    using System.Web.Routing;
    using Routing_Static_Page_Demo.WebHandler;
    
    namespace Routing_Static_Page_Demo
    {
        public class Global : System.Web.HttpApplication
        {
    
            void Application_Start(object sender, EventArgs e)
            {
                RegisterRoutes();
            }
    
            /// <summary>
            /// 注册路由
            /// </summary>
            private void RegisterRoutes()
            {
                
                //将Index.html请求映射为Default.aspx
                RouteTable.Routes.Add("Default",
                                      new Route("Index.html",
                                                new CustomRouteHandler("~/Default.aspx")));
    
                // 将About.html请求映射为About.aspx
                RouteTable.Routes.Add("About",
                                      new Route("About.html",
                                                new CustomRouteHandler("~/About.aspx")));
    
                // 将Account/Login.html请求映射为/Account/Login.aspx
                RouteTable.Routes.Add("Login",
                                      new Route("Account/Login.html",
                                                new CustomRouteHandler("~/Account/Login.aspx")));
            }
        }
    }

    在VS中直接运行站点(VS自带的WebDev服务器),点击这些链接都能够正常访问。

    三.  在IIS 7下设置站点

    下面的设置很重要,因为上面在VS自带的web服务器中虽然跑通了,但IIS 7下是运行不通过的(IIS 6下的设置很简单,本文的在线Demo是运行在IIS 6下的)

    1. 初次在IIS 7下运行该网站,会出现下面的错误。

    SNAGHTML2cedf45

    这是因为IIS对该Web站点目录没有读写权限。

    在IIS下:右键站点 >  Edit Permissions > Security > Edit > Add > 输入IIS_IUSRS > Check Names > OK。

    选择完毕后,为IIS_IUSRS用户添加Full Control权限。

    image

    image

    SNAGHTML2f152df[4]

    2. 添加完该设置后,再运行一次网站,可能会出现下面的错误。

    SNAGHTML2f65a2f

    按照上面的步骤添加IUSR用户,为IUSR用户分配Read权限即可。

    SNAGHTML2f8d75a

    再次运行网站,能够正常访问页面了。

    SNAGHTML2fd7e14

    3.  配置web.config

    网站虽然能运行,但是点击Home或About链接时会出现404错误。

    SNAGHTML2ff02fc

    i. 首先确保在安装IIS时你已经勾选了HTTP Reirection

    如果没有安装这个功能,按照如下设置再配置一遍IIS

    Control Panel --> Progams --> Turn off windows features --> World wide web Services --> Common HTTP Features –> HTTP Redirection

    ii. 修改web.config文件,在webserver中注册RoutingHandler和RoutingModule

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </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" />
        </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>
    
    

    注意: 如果你采用的是ASP.NET 3.5 Routing或使用IIS 6,web.config配置会不一样。

    iii. 确保web站点的应用程序池选择的是集成模式,因为ASP.NET 4.0 Routing并不支持经典模式

    SNAGHTML32bdeab

    OK,似乎所有的该配置的地方都配置了,那么再去点击Index.html或About.html链接试试吧。

    SNAGHTML32d4edb

    如果现在去访问Login.html页面,还是会得到一个401.3的错误,更改Account目录下的web.config文件:

    <?xml version="1.0"?>
    <configuration>
    
      <location path="Register.aspx">
        <system.web>
          <authorization>
            <allow users="*"/>
          </authorization>
        </system.web>
      </location>
    
      <system.web>
        <!--<authorization>
          <deny users="?"/>
        </authorization>-->
      </system.web>
    
    </configuration>
    
    

    如果你不需要这个web.config文件,直接删掉也可以。

    四. 更改RegisterRoutes方法

    上面提供的注册路由的方式属于硬编码,需要为每一个.aspx页面指定映射路由。Account目录下还有一些.aspx文件,如果增加别的目录也存放.aspx页面,为了让每个页面都静态化,RegisterRoutes方法将会是产生很多重复代码。

    using System;
    using System.IO;
    using System.Web.Routing;
    using Routing_Static_Page_Demo.WebHandler;
    
    namespace Routing_Static_Page_Demo
    {
        public class Global : System.Web.HttpApplication
        {
    
            void Application_Start(object sender, EventArgs e)
            {
                RegisterRoutes();
            }
    
            /// <summary>
            /// 注册路由
            /// </summary>
            private void RegisterRoutes()
            {
                
                //将Index.html请求映射为Default.aspx
                RouteTable.Routes.Add("Default",
                                      new Route("Index.html",
                                                new CustomRouteHandler("~/Default.aspx")));
    
                // 将About.html请求映射为About.aspx
                RouteTable.Routes.Add("About",
                                      new Route("About.html",
                                                new CustomRouteHandler("~/About.aspx")));
    
                // 遍历页面存放目录,为每个.aspx页面添加路由映射
                foreach (string mapPth in _pageMapPath)
                {
                    string path = Server.MapPath(mapPth);
                    var directoryInfo = new DirectoryInfo(path);
                    foreach (FileInfo f in directoryInfo.GetFiles())
                    {
                        string fileName = f.Name;
                        if (fileName.EndsWith(".aspx"))
                        {
                            string routeName = fileName.Substring(0, fileName.Length - 5);
                            string url = string.Concat(mapPth.Substring(2), routeName, ".html");
                            RouteTable.Routes.Add(routeName,
                                                  new Route(url,
                                                            new CustomRouteHandler(string.Concat(mapPth, fileName))));
                        }
                    }
                }
                
            }
    
            // 页面存放目录
            private readonly string[] _pageMapPath = {@"~/Account/"};
        }
    }

    以上代码就能实现为每个.aspx页面注册路由实现静态化。

    本文链接: 文章作者:keepfool 文章出处:http://www.cnblogs.com/keepfool/ 如果您觉得阅读本文对您有帮助,请点一右下角的“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎看官们转载,转载之后请给出作者和原文连接。

  • 相关阅读:
    每日日报110
    每日日报109
    每日日报108
    每日日报107
    每日日报106
    每日日报105
    每日日报104
    eclipse新建Maven Project项目后出现The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path问题的解决办法
    0proxy/reflect
    toRefs/toRef/unref/customRef
  • 原文地址:https://www.cnblogs.com/keepfool/p/2426781.html
Copyright © 2011-2022 走看看