老赵同学写过 在Web应用程序开发过程中利用ASP.NET MVC框架的实战技巧 ,Routing现在可以作为URLRewriting技术的替代者,出现在asp.net mvc框架中,将它应用于WebForms上也是很简单的,可以到codeplex上下载ASP.NET MVC WebFormRouting Demo 。
实现的原理也是很简单的:
1、创建一个自定义的实例化你的页面的 IRouteHandler
public class WebFormRouteHandler : IRouteHandler {
public WebFormRouteHandler(string virtualPath) : this(virtualPath, true) {
}
public WebFormRouteHandler(string virtualPath, bool checkPhysicalUrlAccess)
{
if (virtualPath == null)
{
throw new ArgumentNullException("virtualPath");
}
if (!virtualPath.StartsWith("~/")) {
throw new ArgumentException("virtualPath must start with a tilde slash: /"~//"", "virtualPath");
}
this.VirtualPath = virtualPath;
this.CheckPhysicalUrlAccess = checkPhysicalUrlAccess;
}
/// <summary>
/// This is the full virtual path (using tilde syntax) to the WebForm page.
/// </summary>
/// <remarks>
/// Needs to be thread safe so this is only settable via ctor.
/// </remarks>
public string VirtualPath { get; private set; }
/// <summary>
/// Because we're not actually rewriting the URL, ASP.NET's URL Auth will apply
/// to the incoming request URL and not the URL of the physical WebForm page.
/// Setting this to true (default) will apply URL access rules against the
/// physical file.
/// </summary>
/// <value>True by default</value>
public bool CheckPhysicalUrlAccess { get; set; }
public IHttpHandler GetHttpHandler(RequestContext requestContext) {
string virtualPath = GetSubstitutedVirtualPath(requestContext); 38:
if(this.CheckPhysicalUrlAccess && !UrlAuthorizationModule.CheckUrlAccessForPrincipal
(virtualPatrequestContext.HttpContext.User, requestContext.HttpContext.Request.HttpMethod))
throw new SecurityException();
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.
var routablePage = page as IRoutablePage;
if(routablePage != null)
routablePage.RequestContext = requestContext;
}
return page;
}
/// <summary>
/// Gets the virtual path to the resource after applying substitutions based on route data.
/// </summary>
/// <param name="requestContext"></param>
/// <returns></returns>
public string GetSubstitutedVirtualPath(RequestContext requestContext) {
if (!VirtualPath.Contains("{"))
return VirtualPath;
//Trim off ~/
string virtualPath = VirtualPath.Substring(2);
Route route = new Route(virtualPath, this);
VirtualPathData vpd = route.GetVirtualPath(requestContext, requestContext.RouteData.Values);
if (vpd == null)
return VirtualPath;
return "~/" + vpd.VirtualPath;
} 70:
}
2、使用自定义的 IRouteHandler注册一个新的Routes
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterRoutes(RouteCollection routes)
{
//We are intentionally creating this backdoor as a demonstration of
//bad security practices.
routes.MapWebFormRoute("Secret", "BackDoor", "~/Admin/SecretPage.aspx", false);
routes.MapWebFormRoute("Blocked", "FrontDoor", "~/Admin/SecretPage.aspx", true);
//Even though we are not checking physical url access in this route, it should still block because the incoming
//request url would start with /Admin.
routes.MapWebFormRoute("Admin", "Admin/{*anything}", "~/Admin/SecretPage.aspx", false);
routes.MapWebFormRoute("Named", "foo/bar", "~/forms/blech.aspx");
routes.MapWebFormRoute("Numbers", "one/two/three", "~/forms/haha.aspx");
//Maps any requests for /haha/*.aspx to /forms/hahah.aspx
routes.MapWebFormRoute("Substitution", "haha/{filename}", "~/forms/haha.aspx");
}
}
相关文章:
<span id="ctl00_ArticleTopHeader_ArticleTitle" class="ArticleTopTitle">Fight 404 errors with ASP.NET Routing :<a href="http://www.codeproject.com/KB/aspnet/routing404.aspx">http://www.codeproject.com/KB/aspnet/routing404.aspx</a></span>
msdn杂志文章:
使用 ASP.NET Web 窗体路由:http://msdn.microsoft.com/zh-cn/magazine/2009.01.extremeaspnet.aspx