WebForms使用System.Web.Routing

时间:2022-04-23
本文章向大家介绍WebForms使用System.Web.Routing,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

老赵同学写过 在Web应用程序开发过程中利用ASP.NET MVC框架的实战技巧 ,Routing现在可以作为URLRewriting技术的替代者,出现在asp.net mvc框架中,将它应用于WebForms上也是很简单的,可以到codeplex上下载ASP.NET MVC WebFormRouting Demo

实现的原理也是很简单的:

1、创建一个自定义的实例化你的页面的 IRouteHandler

   1: public class WebFormRouteHandler : IRouteHandler {
   2:          public WebFormRouteHandler(string virtualPath)
   3:              : this(virtualPath, true) {
   4:          }
   5:   
   6:          public WebFormRouteHandler(string virtualPath, bool checkPhysicalUrlAccess) {
   7:              if (virtualPath == null) {
   8:                  throw new ArgumentNullException("virtualPath");
   9:              }
  10:   
  11:              if (!virtualPath.StartsWith("~/")) {
  12:                  throw new ArgumentException("virtualPath must start with a tilde slash: "~/"", "virtualPath");
  13:              }
  14:   
  15:              this.VirtualPath = virtualPath;
  16:              this.CheckPhysicalUrlAccess = checkPhysicalUrlAccess;
  17:          }
  18:   
  19:          /// <summary>
  20:          /// This is the full virtual path (using tilde syntax) to the WebForm page.
  21:          /// </summary>
  22:          /// <remarks>
  23:          /// Needs to be thread safe so this is only settable via ctor.
  24:          /// </remarks>
  25:          public string VirtualPath { get; private set; }
  26:   
  27:          /// <summary>
  28:          /// Because we're not actually rewriting the URL, ASP.NET's URL Auth will apply 
  29:          /// to the incoming request URL and not the URL of the physical WebForm page.
  30:          /// Setting this to true (default) will apply URL access rules against the 
  31:          /// physical file.
  32:          /// </summary>
  33:          /// <value>True by default</value>
  34:          public bool CheckPhysicalUrlAccess { get; set; }
  35:   
  36:          public IHttpHandler GetHttpHandler(RequestContext requestContext) {
  37:              string virtualPath = GetSubstitutedVirtualPath(requestContext);
  38:              if (this.CheckPhysicalUrlAccess && !UrlAuthorizationModule.CheckUrlAccessForPrincipal(virtualPath, requestContext.HttpContext.User, requestContext.HttpContext.Request.HttpMethod))
  39:                  throw new SecurityException();
  40:   
  41:              var page = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page)) as IHttpHandler;
  42:              if (page != null) {
  43:                  //Pages that don't implement IRoutablePage won't have the RequestContext
  44:                  //available to them. Can't generate outgoing routing URLs without that context.
  45:                  var routablePage = page as IRoutablePage;
  46:                  if (routablePage != null)
  47:                      routablePage.RequestContext = requestContext;
  48:              }
  49:              return page;
  50:          }
  51:   
  52:          /// <summary>
  53:          /// Gets the virtual path to the resource after applying substitutions based on route data.
  54:          /// </summary>
  55:          /// <param name="requestContext"></param>
  56:          /// <returns></returns>
  57:          public string GetSubstitutedVirtualPath(RequestContext requestContext) {
  58:              if (!VirtualPath.Contains("{"))
  59:                  return VirtualPath;
  60:   
  61:              //Trim off ~/
  62:              string virtualPath = VirtualPath.Substring(2);
  63:   
  64:              Route route = new Route(virtualPath, this);
  65:              VirtualPathData vpd = route.GetVirtualPath(requestContext, requestContext.RouteData.Values);
  66:              if (vpd == null)
  67:                  return VirtualPath;
  68:              return "~/" + vpd.VirtualPath;
  69:          }
  70:      }

2、使用自定义的 IRouteHandler注册一个新的Routes

   1:  public class Global : System.Web.HttpApplication
   2:      {
   3:   
   4:          protected void Application_Start(object sender, EventArgs e)
   5:          {
   6:              RegisterRoutes(RouteTable.Routes);
   7:          }
   8:   
   9:          public static void RegisterRoutes(RouteCollection routes)
  10:          {
  11:              //We are intentionally creating this backdoor as a demonstration of 
  12:              //bad security practices.
  13:              routes.MapWebFormRoute("Secret", "BackDoor", "~/Admin/SecretPage.aspx", false);
  14:              routes.MapWebFormRoute("Blocked", "FrontDoor", "~/Admin/SecretPage.aspx", true);
  15:   
  16:              //Even though we are not checking physical url access in this route, it should still block because the incoming 
  17:              //request url would start with /Admin.
  18:              routes.MapWebFormRoute("Admin", "Admin/{*anything}", "~/Admin/SecretPage.aspx", false);
  19:   
  20:              routes.MapWebFormRoute("Named", "foo/bar", "~/forms/blech.aspx");
  21:              routes.MapWebFormRoute("Numbers", "one/two/three", "~/forms/haha.aspx");
  22:              
  23:              //Maps any requests for /haha/*.aspx to /forms/hahah.aspx
  24:              routes.MapWebFormRoute("Substitution", "haha/{filename}", "~/forms/haha.aspx");
  25:          }
  26:      }

msdn杂志文章: 使用 ASP.NET Web 窗体路由:http://msdn.microsoft.com/zh-cn/magazine/2009.01.extremeaspnet.aspx