Routing with WebForms

http://haacked.com/archive/2008/03/11/using-routing-with-webforms.aspx
http://haacked.com/archive/2008/05/19/updated-routing-with-webforms.aspx

ASP.NET MVC 框架中包含了 Routing 的功能,由 System.Web.Routing 提供。但这个功能并不局限于 MVC,而且已经从中分离出来成为了一个独立的组件。

Phil Haack 的 blog 中提出一种办法可以配合 WebForm 使用 Routing 功能。这里有几个关键点。

首先,需要实现一个 IRouteHandler,它是一个 IHttpHandler 的提供者。

namespace  System.Web.Routing
{
    
public   interface  IRouteHandler
    {
        IHttpHandler GetHttpHandler(RequestContext requestContext);
    }
}

这里 Phil 创建实现了一个 WebFormRouteHandler.  其关键代码如下:

namespace  WebFormRouting
{
    
public   class  WebFormRouteHandler : IRouteHandler
    {
        
//  

        
public  IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            
//  根据 RouteData 得到被替换后的虚拟路径
             string  virtualPath  =  GetSubstitutedVirtualPath(requestContext);

            
//  对 URL 进行身份验证(如果需要)
             if  ( this .CheckPhysicalUrlAccess  &&   ! UrlAuthorizationModule.CheckUrlAccessForPrincipal(virtualPath, requestContext.HttpContext.User, requestContext.HttpContext.Request.HttpMethod))
                
throw   new  SecurityException();

            
//  根据虚拟路径创建 Page 对象
            var page  =  BuildManager.CreateInstanceFromVirtualPath(virtualPath,  typeof (Page))  as  IHttpHandler;
            
if  (page  !=   null )
            {
                
// Pages that don't implement IRoutablePage won't have the RequestContext
                
// available to them. Can't generate outgoing routing URLs without that context.

                
//  查看页面是否实现了 IRoutablePage (包含 RequestContext 属性,可产生出去的 routing URLs)
                
//  设置其 RequestContext
                var routablePage  =  page  as  IRoutablePage;
                
if  (routablePage  !=   null )
                    routablePage.RequestContext 
=  requestContext;
            }
            
return  page;
        }
    }
}

在通过路由信息找到相关的 Page 后,能够通过 System.Web.Compilation.BuildManager 的 CreateInstanceFromVirtualPath 方法,接受一个虚拟路径和所需创建的 Page 类型,即可创建出相应的 Page 对象来处理请求。

我看了目前 ASP.NET MVC 框架的实现,其中默认的视图引擎 WebFormViewEngine 也是通过了这个方法来创建相关的 Page 对象。

需要注意的是,Routing 和 URL Rewrite 是有区别的,我的理解是 Routing 比 URL Rewrite 发生的更早,并不会在内部发起一个新的 Request.
因此 Phil 提到需要注意的一个安全问题,就是结合窗体身份验证时,如果不注意,Routing 会跳过身份验证这个环节的监测。因此,上面代码中的 UrlAuthorizationModule.CheckUrlAccessForPrincipal 方法调用就是对这个问题的补救。

同样基于这个区别的原因,Routing 的目标地址不可以带 QueryString 参数,变通的办法是可以通过 RouteData 传递参数。

你可能感兴趣的:(.NET)