折腾一个自己的UrlRewrite
2011-08-16 21:58 飞魚 阅读(2042) 评论(1) 编辑 收藏 举报UrlRewrite一般都是在web.config里配置访问规则在路由到实际页面,所以先实现自定义节点信息读取,这里我定义了俩个类,贴出详细信息
namespace UrlRewrite { public class UrlRewriteConfigGroup : ConfigurationSectionGroup { [ConfigurationProperty("rules")] public UrlRewriteConfig Rules { get { return (UrlRewriteConfig)base.Sections["rules"]; } } } }
namespace UrlRewrite { public class UrlRewriteConfig : ConfigurationSection { [ConfigurationProperty("enable", DefaultValue = false)] public bool Enable { get { return (bool)base["enable"]; } } [ConfigurationProperty("suffix", DefaultValue = ".html")] public string Suffix { get { return (string)base["suffix"]; } } [ConfigurationProperty("", IsDefaultCollection = true)] public RulesElectionCollection Rules { get { return (RulesElectionCollection)base[""]; } } } public class UrlRewriteConfigRule : ConfigurationElement { [ConfigurationProperty("form")] public string Form { get { return (string)base["form"]; } } [ConfigurationProperty("to")] public string To { get { return (string)base["to"]; } } [ConfigurationProperty("query")] public string Query { get { return (string)base["query"]; } } } public class RulesElectionCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new UrlRewriteConfigRule(); } protected override object GetElementKey(ConfigurationElement element) { return ((UrlRewriteConfigRule)element).Form; } } public static class UrlRewriteConfigHelp { public static bool Enabled { get { UrlRewriteConfig section = ConfigurationManager.GetSection("rulesGroup/rules") as UrlRewriteConfig; if (section == null) { return false; } return section.Enable; } } public static string Suffix { get { UrlRewriteConfig section = ConfigurationManager.GetSection("rulesGroup/rules") as UrlRewriteConfig; if (section == null) { return ".html"; } return section.Suffix; } } public static RulesElectionCollection Rules { get { UrlRewriteConfig section = ConfigurationManager.GetSection("rulesGroup/rules") as UrlRewriteConfig; if (section == null) { throw new System.InvalidOperationException("未能获取rulesGroup/rules"); } return section.Rules; } } public static string RewriteBase { get { string path = HttpContext.Current.Request.ApplicationPath; if (!path.EndsWith("/")) { return path + "/"; } return path; } } } }
这里定义了组,不需要的话可以把UrlRewriteConfigGroup类去掉并修改配置节点,在UrlRewriteConfig类里又定义了UrlRewriteConfigHelp帮助类获取节点信息...
然后实现IHttpModule实现重写
namespace UrlRewrite { public class UrlRewrite : IHttpModule { #region IHttpModule 成员 public void Dispose() { throw new NotImplementedException(); } public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(Application_BeginRequest); //context.PreRequestHandlerExecute += new EventHandler(Application_PreRequestHandlerExecute); } void Application_BeginRequest(object sender, EventArgs e) { HttpContext context = HttpContext.Current; // 取得当前请求的路径 string path = context.Request.Path; string suffix = String.Empty; if (UrlRewriteConfigHelp.Enabled) suffix = UrlRewriteConfigHelp.Suffix; // 遍历所有的映射规则,进行映射处理 foreach (UrlRewriteConfigRule rule in UrlRewriteConfigHelp.Rules) { Regex regex = new Regex("^" + rule.Form + suffix + "$", RegexOptions.IgnoreCase); Match match = regex.Match(path); if (match.Success) { string trueUrl = UrlRewriteConfigHelp.RewriteBase + rule.To; context.Items["OriginalUrl"] = context.Request.RawUrl; if ("POST".Equals(context.Request.HttpMethod)) trueUrl = trueUrl.Substring(0, trueUrl.LastIndexOf("?")); else { int count = match.Groups.Count; if (count > 1 && match.Groups[1].Value != "") { for (int i = 1; i <= count; i++) { trueUrl = trueUrl.Replace("$" + i, match.Groups[i + 1].Value); } } } context.RewritePath(trueUrl); return; } } //context.RewritePath("/error.htm"); }
然后就可以访问了
这里from的action生成的是实际的地址,为了能让form生成请求的地址要重写form的action生成,这里定义了一个form.browser文件和一个FormRewriterControlAdapter类
namespace UrlRewrite { public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter { protected override void Render(HtmlTextWriter writer) { base.Render(new RewriteFormHtmlTextWriter(writer)); } } public class RewriteFormHtmlTextWriter : HtmlTextWriter { public RewriteFormHtmlTextWriter(HtmlTextWriter writer) : base(writer) { this.InnerWriter = writer.InnerWriter; } public RewriteFormHtmlTextWriter(TextWriter writer) : base(writer) { this.InnerWriter = writer; } public override void WriteAttribute(string name, string value, bool fEncode) { if (name == "action") { HttpContext context = HttpContext.Current; if (context.Items["ActionAlreadyWritten"] == null) { value = context.Items["OriginalUrl"] as string; context.Items["ActionAlreadyWritten"] = true; } } base.WriteAttribute(name, value, fEncode); } } }
form.browser文件代码
<!--
可在 <windir>\Microsoft.NET\Framework\<ver>\CONFIG\Browsers 中找到现有的浏览器定义
-->
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
adapterType="UrlRewrite.FormRewriterControlAdapter" />
</controlAdapters>
</browser>
</browsers>
整体截图
另外web.config中
<rules enable="true" suffix=".ygm">
<add form="(/|/default|/index)" to="view/user/index.aspx"/>
<add form="/u/user(_(\d+))*" to="view/user/user.aspx?id=$1" />
</rules>
enable设置为true启动带后缀的访问,suffix设置后缀名,可以随便起
设置后访问截图
由于没怎么用过urlrewrite重写和.net下正则也比较生疏所以折腾下,貌似可以不用.browsers文件也可以达到form的action正确生成,望指教..
最后附上源码下载