URLRewriter.Config名称空间 RewriterConfigSerializerSectionHandler.cs 这个类返回一个反序列化 XML 文档 using System; using System.Configuration; using System.Xml; using System.Xml.Serialization; using System.Xml.XPath; namespace URLRewriter.Config { public class RewriterConfigSerializerSectionHandler : IConfigurationSectionHandler { public object Create(object parent, object configContext, System.Xml.XmlNode section) { // Create an instance of XmlSerializer based on the RewriterConfiguration type... XmlSerializer ser = new XmlSerializer(typeof(RewriterConfiguration)); // Return the Deserialized object from the Web.config XML return ser.Deserialize(new XmlNodeReader(section)); } } } RewriterConfiguration.cs 返回配制节点信息 using System; using System.Web; using System.Web.Caching; using System.Configuration; using System.Xml.Serialization; namespace URLRewriter.Config { [Serializable()] [XmlRoot("RewriterConfig")] public class RewriterConfiguration { // private member variables private RewriterRuleCollection rules; // an instance of the public static RewriterConfiguration GetConfig() { if (HttpContext.Current.Cache["RewriterConfig"] == null) HttpContext.Current.Cache.Insert("RewriterConfig", ConfigurationSettings.GetConfig("RewriterConfig")); return (RewriterConfiguration) HttpContext.Current.Cache["RewriterConfig"]; } #region Public Properties /// <summary> /// A <see cref="RewriterRuleCollection"/> instance that provides access to a set of <see cref="RewriterRule"/>s. /// </summary> public RewriterRuleCollection Rules { get { return rules; } set { rules = value; } } #endregion } } RewriterRuleCollection.cs 方法 using System; using System.Collections; namespace URLRewriter.Config { [Serializable()] public class RewriterRuleCollection : CollectionBase { /// <summary> /// Adds a new RewriterRule to the collection. /// </summary> /// <param name="r">A RewriterRule instance.</param> public virtual void Add(RewriterRule r) { this.InnerList.Add(r); } /// <summary> /// Gets or sets a RewriterRule at a specified ordinal index. /// </summary> public RewriterRule this[int index] { get { return (RewriterRule) this.InnerList[index]; } set { this.InnerList[index] = value; } } } } RewriterRule.cs 定义的属性 using System; namespace URLRewriter.Config { public class RewriterRule { private string lookFor, sendTo; public string LookFor { get { return lookFor; } set { lookFor = value; } } public string SendTo { get { return sendTo; } set { sendTo = value; } } } } URLRewriter名称空间 这个里对上面的rules进行处理 BaseModuleRewriter.cs 初始化,加载方法 using System; using System.Web; namespace URLRewriter { public abstract class BaseModuleRewriter : IHttpModule { public virtual void Init(HttpApplication app) { app.AuthorizeRequest += new EventHandler(this.BaseModuleRewriter_AuthorizeRequest); } public virtual void Dispose() {} protected virtual void BaseModuleRewriter_AuthorizeRequest(object sender, EventArgs e) { HttpApplication app = (HttpApplication) sender; Rewrite(app.Request.Path, app); } protected abstract void Rewrite(string requestedPath, HttpApplication app); } } ModuleRewriter.cs 循环出每个rule执行RewriteUrl using System; using System.Text.RegularExpressions; using System.Configuration; using URLRewriter.Config; namespace URLRewriter { /// <summary> /// Provides a rewriting HttpModule. /// </summary> public class ModuleRewriter : BaseModuleRewriter { /// <summary> /// This method is called during the module's BeginRequest event. /// </summary> /// <param name="requestedRawUrl">The RawUrl being requested (includes path and querystring).</param> /// <param name="app">The HttpApplication instance.</param> protected override void Rewrite(string requestedPath, System.Web.HttpApplication app) { // log information to the Trace object. //app.Context.Trace.Write("ModuleRewriter", "Entering ModuleRewriter"); // get the configuration rules RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules; // iterate through each rule... for(int i = 0; i < rules.Count; i++) { // get the pattern to look for, and Resolve the Url (convert ~ into the appropriate directory) string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor) + "$"; // Create a regex (note that IgnoreCase is set...) Regex re = new Regex(lookFor, RegexOptions.IgnoreCase); // See if a match is found if (re.IsMatch(requestedPath)) { // match found - do any replacement needed string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo)); // log rewriting information to the Trace object app.Context.Trace.Write("ModuleRewriter", "Rewriting URL to " + sendToUrl); // Rewrite the URL RewriterUtils.RewriteUrl(app.Context, sendToUrl); break; // exit the for loop } } // Log information to the Trace object app.Context.Trace.Write("ModuleRewriter", "Exiting ModuleRewriter"); } } } RewriterUtils.cs 根据设定的路径转换URL并进行RewritePath 可以看到最后,只是执行了context.RewritePath(path)方法,在httphandle中,用的是context.Server.Transfer(url) using System; using System.Web; namespace URLRewriter { /// <summary> /// Provides utility helper methods for the rewriting HttpModule and HttpHandler. /// </summary> /// <remarks>This class is marked as internal, meaning only classes in the same assembly will be /// able to access its methods.</remarks> internal class RewriterUtils { #region RewriteUrl /// <summary> /// Rewrite's a URL using <b>HttpContext.RewriteUrl()</b>. /// </summary> /// <param name="context">The HttpContext object to rewrite the URL to.</param> /// <param name="sendToUrl">The URL to rewrite to.</param> internal static void RewriteUrl(HttpContext context, string sendToUrl) { string x, y; RewriteUrl(context, sendToUrl, out x, out y); } /// <summary> /// Rewrite's a URL using <b>HttpContext.RewriteUrl()</b>. /// </summary> /// <param name="context">The HttpContext object to rewrite the URL to.</param> /// <param name="sendToUrl">The URL to rewrite to.</param> /// <param name="sendToUrlLessQString">Returns the value of sendToUrl stripped of the querystring.</param> /// <param name="filePath">Returns the physical file path to the requested page.</param> internal static void RewriteUrl(HttpContext context, string sendToUrl, out string sendToUrlLessQString, out string filePath) { // see if we need to add any extra querystring information if (context.Request.QueryString.Count > 0) { if (sendToUrl.IndexOf('?') != -1) sendToUrl += "&" + context.Request.QueryString.ToString(); else sendToUrl += "?" + context.Request.QueryString.ToString(); } // first strip the querystring, if any string queryString = String.Empty; sendToUrlLessQString = sendToUrl; if (sendToUrl.IndexOf('?') > 0) { sendToUrlLessQString = sendToUrl.Substring(0, sendToUrl.IndexOf('?')); queryString = sendToUrl.Substring(sendToUrl.IndexOf('?') + 1); } // grab the file's physical path filePath = string.Empty; filePath = context.Server.MapPath(sendToUrlLessQString); // rewrite the path... context.RewritePath(sendToUrlLessQString, String.Empty, queryString); // NOTE! The above RewritePath() overload is only supported in the .NET Framework 1.1 // If you are using .NET Framework 1.0, use the below form instead: // context.RewritePath(sendToUrl); } #endregion /// <summary> /// Converts a URL into one that is usable on the requesting client. /// </summary> /// <remarks>Converts ~ to the requesting application path. Mimics the behavior of the /// <b>Control.ResolveUrl()</b> method, which is often used by control developers.</remarks> /// <param name="appPath">The application path.</param> /// <param name="url">The URL, which might contain ~.</param> /// <returns>A resolved URL. If the input parameter <b>url</b> contains ~, it is replaced with the /// value of the <b>appPath</b> parameter.</returns> internal static string ResolveUrl(string appPath, string url) { if (url.Length == 0 || url[0] != '~') return url; // there is no ~ in the first character position, just return the url else { if (url.Length == 1) return appPath; // there is just the ~ in the URL, return the appPath if (url[1] == '/' || url[1] == '\\') { // url looks like ~/ or ~\ if (appPath.Length > 1) return appPath + "/" + url.Substring(2); else return "/" + url.Substring(2); } else { // url looks like ~something if (appPath.Length > 1) return appPath + "/" + url.Substring(1); else return appPath + url.Substring(1); } } } } } 以上仅个人愚见,难免有错误 |