【转】利用IHttpHandler实现ASP.NET URL重写
IHttpHandler接口实现类OwnHttpHandler:
程序代码如下:
using System;
using System.Web;
using System.Text.RegularExpressions;
using System.Collections.Generic;
/// <summary>
///IHttpHandler 接口实现类
/// </summary>
public class OwnHttpHandler : IHttpHandler
{
#region IHttpHandler 成员
/// <summary>
/// 当前处理器是否还可以被另一个请求重复使用
/// </summary>
public bool IsReusable
{
get { return true; }
}
/// <summary>
/// 对请求响应时,实际执行的代码
/// </summary>
/// <param name="context"></param>
public void ProcessRequest(HttpContext context)
{
//这边为方便演示直接往集合添加规则,实际应用可考虑将规则写到配置文件中再读取
Dictionary<string, string> rules = new Dictionary<string, string>();
rules.Add(@"^/news/(\w+)\.aspx", "/news.aspx?t=$1");
rules.Add(@"^/soft/(\w+)\.aspx", "/soft.aspx?t=$1");
rules.Add(@"^/music/(\w+)\.aspx", "/music.aspx?t=$1");
foreach (KeyValuePair<string, string> rule in rules)
{
Match match = Regex.Match(context.Request.Path, rule.Key, RegexOptions.IgnoreCase);
if (match.Success)
{
string sendToUrl = Regex.Replace(context.Request.Path, rule.Key, rule.Value, RegexOptions.IgnoreCase);
string path = sendToUrl;//虚拟路径
string querystring = string.Empty;//查询参数
if (sendToUrl.IndexOf("?") != -1)
{
path = sendToUrl.Substring(0, sendToUrl.IndexOf("?"));
querystring = sendToUrl.Substring(sendToUrl.IndexOf("?") + 1);
}
context.Server.Execute(path + "?" + querystring);
return;
}
}
context.Response.Write("404:页面未找到!");
}
#endregion
}
using System.Web;
using System.Text.RegularExpressions;
using System.Collections.Generic;
/// <summary>
///IHttpHandler 接口实现类
/// </summary>
public class OwnHttpHandler : IHttpHandler
{
#region IHttpHandler 成员
/// <summary>
/// 当前处理器是否还可以被另一个请求重复使用
/// </summary>
public bool IsReusable
{
get { return true; }
}
/// <summary>
/// 对请求响应时,实际执行的代码
/// </summary>
/// <param name="context"></param>
public void ProcessRequest(HttpContext context)
{
//这边为方便演示直接往集合添加规则,实际应用可考虑将规则写到配置文件中再读取
Dictionary<string, string> rules = new Dictionary<string, string>();
rules.Add(@"^/news/(\w+)\.aspx", "/news.aspx?t=$1");
rules.Add(@"^/soft/(\w+)\.aspx", "/soft.aspx?t=$1");
rules.Add(@"^/music/(\w+)\.aspx", "/music.aspx?t=$1");
foreach (KeyValuePair<string, string> rule in rules)
{
Match match = Regex.Match(context.Request.Path, rule.Key, RegexOptions.IgnoreCase);
if (match.Success)
{
string sendToUrl = Regex.Replace(context.Request.Path, rule.Key, rule.Value, RegexOptions.IgnoreCase);
string path = sendToUrl;//虚拟路径
string querystring = string.Empty;//查询参数
if (sendToUrl.IndexOf("?") != -1)
{
path = sendToUrl.Substring(0, sendToUrl.IndexOf("?"));
querystring = sendToUrl.Substring(sendToUrl.IndexOf("?") + 1);
}
context.Server.Execute(path + "?" + querystring);
return;
}
}
context.Response.Write("404:页面未找到!");
}
#endregion
}
使用非常简单,只需在配置文件web.config的<system.web>节点中加入下边节点即可
配置代码如下:
<httpHandlers>
<add verb="*" path="/news/*.aspx" type="OwnHttpHandler" />
<add verb="*" path="/soft/*.aspx" type="OwnHttpHandler" />
<add verb="*" path="/music/*.aspx" type="OwnHttpHandler" />
</httpHandlers>
<add verb="*" path="/news/*.aspx" type="OwnHttpHandler" />
<add verb="*" path="/soft/*.aspx" type="OwnHttpHandler" />
<add verb="*" path="/music/*.aspx" type="OwnHttpHandler" />
</httpHandlers>
附加说明
·是否需重写,两者都是对路径进行匹配来决定,HTTP模块可以用正则,HTTP处理程序只能用通配符*、?;
·HTTP模块的匹配规则可以放在任何可调用到的地方,HTTP处理程序的匹配规则只能放在配置文件中;
·所有HTTP模块在请求时都会被调用,一次请求中只有路径和path属性值匹配的那个HTTP处理程序才会被调用;
·如果HTTP模块中不理行重写那将访问真实文件,HTTP处理程序中不进行重写访问不到真实文件,显示空白页;
·HTTP模块的匹配规则可以放在任何可调用到的地方,HTTP处理程序的匹配规则只能放在配置文件中;
·所有HTTP模块在请求时都会被调用,一次请求中只有路径和path属性值匹配的那个HTTP处理程序才会被调用;
·如果HTTP模块中不理行重写那将访问真实文件,HTTP处理程序中不进行重写访问不到真实文件,显示空白页;
转发目的是想寻求更多的爱好者一起探讨。此方案在研究中,如果有心得会进行补充。
原文地址:http://www.mzwu.com/article.asp?id=1907
(MSDN)在 ASP.NET 中执行 URL 重写:http://msdn.microsoft.com/zh-cn/library/ms972974.aspx