好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ASP.NET 路由实现页面静态化(附在线Demo和Source)

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点。

本文已经同步至我的个人博客站点: 积累吧 | ASP.NET 路由实现页面静态化

源代码下载: https://files.cnblogs.com/keepfool/UrlRouting.zip

在线Demo: http://csdemo.jileiba.com/UrlRouting/

一、项目创建

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

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中

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

二、页面静态化实现

1. 添加Routing引用

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

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下运行该网站,会出现下面的错误。

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

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

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

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

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

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

3.  配置web.config

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

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并不支持经典模式

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

如果现在去访问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页面注册路由实现静态化。

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.

随笔分类 -【1】ASP.NET Dev

ASP.NET 路由实现页面静态化(附在线Demo和Source) 2012-03-31 12:48 by keepfool, 866 visits,  网摘 ,  收藏 ,  编辑

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

10 Comment Categories:  【1】ASP.NET Dev

Repeater排序的三种实现方式(附在线Demo) 2012-03-18 22:04 by keepfool, 1308 visits,  网摘 ,  收藏 ,  编辑

摘要: Repeater控件是较为干净的服务端数据控件,它不像GridView已经包含了分页和排序功能,这两个小功能都要咱们自己去实现。由于分页的功能很容易实现,我也没什么好讲的;下文中我提供了三种排序方式,除了传统方式以外,另外两种都较为简便灵活。 在线Demo: Demo - Repeater 传统排序 Demo - Repeater 反射排序方式 Demo - Repeat...  阅读全文

5 Comment Categories:  【1】ASP.NET Dev

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于ASP.NET 路由实现页面静态化(附在线Demo和Source)的详细内容...

  阅读:37次