现在在.net中,我们有很多方法可以实现路径的重写,不论是外部插件还是代码控制,总归是为了让URL对外更加的短小,易懂并且不包含敏感信息.
所以,在这里,我主要介绍如何利用PageHandlerFactory类来拦截URL请求并且进行重写的.
这里类是所有的aspx页面请求的默认父类对象,页面的任何请求都可以被其捕获,我们可以通过重写其中的getHandler方法来实现自我控制.
功能需求
不过,在开始写之前,我们先看看我们需要用到什么功能.
- URL重写需要支持GET, POST请求方式.
- URL重写需要支持实时的DEBUG功能,也就是能够跳转到重新定向的页面进行调试.
代码构建
基于这两点(其实这两点在开发过程中也是很重要的两点),我们构建如下的代码页:
using System.Web; using System.Web.UI; using System.Web.SessionState; using System; namespace AsyncFactoryWEB { public class RewriterFactory : PageHandlerFactory,IReadOnlySessionState { private bool flag = true; public override IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path) { string[] urlSegments = context.Request.Url.Segments; //获取URL片段 int urlLen = urlSegments.Length; //获取URL的片段长度 if (urlLen <= 1) //当前请求为根目录页面,则不进行处理 flag = false; else //当前请求不是根目录页面,进行处理 flag = true; if (flag) { string conceratePath = ((char)RewriteSettings.splitter.slash).ToString(); string slashChar = ((char)RewriteSettings.splitter.slash).ToString(); // /斜线 string equalChar = ((char)RewriteSettings.splitter.equal).ToString(); // =等号 string andChar = ((char)RewriteSettings.splitter.and ).ToString(); // &符号 string extension = ((char)RewriteSettings.splitter.dot ).ToString().Combine(RewriteSettings.fileExtension.aspx.ToString()); // .aspx后缀 string concerateParams=string.Empty; for (int i = 0; i < urlLen; i++) { string curSegment = urlSegments[i]; if (curSegment.LastIndexOf(slashChar) >= 0) //如果检测片段中带有左斜线 curSegment = curSegment.Substring(0, curSegment.Length - 1); //将斜线去掉 if (!string.IsNullOrEmpty(curSegment)) { if (curSegment.Contains(equalChar)) //如果带有等号,则表明应该进行 ***.aspx?id=1 类似的拼接 { if (i == urlLen - 1) concerateParams = concerateParams.Combine(curSegment); else concerateParams = concerateParams.Combine(curSegment.Combine(andChar)); } else if (!curSegment.EndsWith(extension)) //如果不是以.aspx结尾的 conceratePath = conceratePath.Combine(curSegment.Combine(extension)); else conceratePath = conceratePath.Combine(curSegment); } } string newPath = context.Server.MapPath(conceratePath); //得到物理目录 context.RewritePath(conceratePath, string.Empty, concerateParams); //重写路径,并传入parameters try { IHttpHandler iHandler = PageParser.GetCompiledPageInstance(conceratePath, newPath, context); //重写handler对象 return iHandler; } catch (Exception ex) { throw new Exception(ex.Message); } } else { return base.GetHandler(context, requestType, virtualPath, path); } } } }