在。NET中实现URL重写有两种方法
httphandle和Urlriter
httphandle请看这里
Urlriter原文在这里
可以下载到例子的原代码
基本过程可以通过web.onfig得之
设置一个处理类
configSections>
    <section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
  </configSections>
配制处理的URL
<ewriterConfig>
 <Rules>
  <!-- Rules for Blog Content Displayer -->
  <RewriterRule>
   <LookFor>~/abc/.aspx</LookFor>
   <SendTo>~/index.aspx</SendTo>
  </RewriterRule>
   </Rules>
  </RewriterConfig>
为 URL 重写引擎指定配置信息
  <system.web>
   <httpModules>
  <add type="URLRewriter.ModuleRewriter, URLRewriter" name="ModuleRewriter" />
 </httpModules>
  </ystem.web>
思路就是这样的了,和httphandle不同,httphandle就像系统自带的,需要你去写配制文件处理,直接就可以用,并且可以在内部处理请求输出
Urlriter则需要你去写,它的好处是对于web.config中配制,你不必像httphandle一样为每一个节点去写一个类

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);
    }
   }
  }
 }
}

以上仅个人愚见,难免有错误


本文转载:CSDN博客