在。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);
}
}
}
}
}
以上仅个人愚见,难免有错误