根据微软官方伪静态UrlRewrite.dll源码,自己改写应用进项目中。
1、首先,我们写个用于HttpModule请求的类 RolesProvider
using System;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Security.Principal;
public class RolesProvider : IHttpModule
{
//页面初始化
public void Init(HttpApplication context)
{
context.AuthorizeRequest += new EventHandler(this.BaseModuleRewriter_AuthorizeRequest);
context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
//context.BeginRequest += new EventHandler(context_BeginRequest);
context.Error += new EventHandler(context_Error);
}
/// <summary>
/// 伪静态处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void BaseModuleRewriter_AuthorizeRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
string host = context.Request.ServerVariables["HTTP_HOST"].ToLower(); //获取当前主机头
string requestPath = context.Request.Path.ToLower(); //当前请求路径 不带域名
/**这边也可以做301处理功能**/
context.Trace.Write("ModuleRewriter", "Entering ModuleRewriter");
UtilsUrlRewrite.UrlRewrite(RewriterConfiguration.GetConfig("ConfigUrlRewrite", "ConfigUrlRewrite.config"), requestPath, context); //伪静态核心代码 详见下UtilsUrlRewrite.cs
context.Trace.Write("ModuleRewriter", "Exiting ModuleRewriter"); }
/// <summary>
/// 建立用户标识时
/// </summary>
void context_AuthenticateRequest(object sender, EventArgs e)
{
}
/// <summary>
/// 请求出错时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void context_Error(object sender, EventArgs e)
{
/*CmsSafe.UrlError();*/
}
public void Dispose()
{
}
}
2、UtilsUrlRewrite.cs 伪静态处理核心代码
/**
由于是参考官网例子,伪静态规则语法不变。以下代码可直接复制,设置下伪静态文件地址就可以。
**/
using System;
using System.Web;
using System.Web.Caching;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Xml;
using System.Xml.Serialization;
using System.Text.RegularExpressions;
public class UtilsUrlRewrite
{
public static void UrlRewrite(RewriterRuleCollection rules, string requestPath, HttpContext context)
{
for (int i = 0; i < rules.Count; i++)
{
string lookFor = "^" + UtilsUrlRewrite.ResolveUrl(context.Request.ApplicationPath, rules[i].LookFor) + "$";
Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);
if (re.IsMatch(requestPath))
{
string sendToUrl = UtilsUrlRewrite.ResolveUrl(context.Request.ApplicationPath, re.Replace(requestPath, rules[i].SendTo));
context.Trace.Write("ModuleRewriter", "Rewriting URL to " + sendToUrl);
UtilsUrlRewrite.RewriteUrl(context, sendToUrl);
break;
}
}
}
internal static void RewriteUrl(HttpContext context, string sendToUrl)
{
// 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();
}
string queryString = String.Empty;
string sendToUrlLessQString = sendToUrl;
if (sendToUrl.IndexOf('?') > 0)
{
sendToUrlLessQString = sendToUrl.Substring(0, sendToUrl.IndexOf('?'));
queryString = sendToUrl.Substring(sendToUrl.IndexOf('?') + 1);
}
context.RewritePath(sendToUrlLessQString, String.Empty, queryString);
}
internal static string ResolveUrl(string appPath, string url)
{
if (url.Length == 0 || url[0] != '~')
return url;
else
{
if (url.Length == 1)
return appPath;
if (url[1] == '/' || url[1] == '\\')
{
if (appPath.Length > 1)
return appPath + "/" + url.Substring(2);
else
return "/" + url.Substring(2);
}
else
{
if (appPath.Length > 1)
return appPath + "/" + url.Substring(1);
else
return appPath + url.Substring(1);
}
}
}
}
[Serializable()]
[XmlRoot("RewriterConfig")]
public class RewriterConfiguration
{
public static RewriterRuleCollection GetConfig(string cache, string filename)
{
if (HttpContext.Current.Cache[cache] == null)
{
RewriterRuleCollection rc = new RewriterRuleCollection();
RewriterRule r;
string filePath = UtilsString.MapPath("~/App_Data/" + filename); //伪静态文件地址
XmlDocument xd = new XmlDocument();
xd.Load(filePath);
XmlNodeList items = xd.DocumentElement.ChildNodes;
foreach (XmlNode item in items)
{
if (item.HasChildNodes == true)
{
r = new RewriterRule();
r.LookFor = item["LookFor"].InnerText;
r.SendTo = item["SendTo"].InnerText;
rc.Add(r);
}
}
UtilsCache.AddCache(cache, rc, UtilsCache.GetCacheDependency(filePath));
return rc;
}
return (RewriterRuleCollection)HttpContext.Current.Cache[cache];
}
}
[Serializable()]
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;
}
}
}
[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;
}
}
}
}
3、伪静态规则文件 ConfigUrlRewrite.config ,只列出有代表性的规则
<?xml version="1.0"?>
<RewriterConfig>
<RewriterRule>
<LookFor>~/404.(html|aspx)</LookFor>
<SendTo>~/default.aspx?s=404</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>~/([\w]+)-list([0-9]+).(html|aspx)</LookFor>
<SendTo>~/default.aspx?s=$1&menuid=$2</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>~/([\w]+)-id([0-9]+).(html|aspx)</LookFor>
<SendTo>~/default.aspx?s=$1&id=$2</SendTo>
</RewriterRule>
</RewriterConfig>
4、在网站根目录web.config中注册HttpModule
<?xml version="1.0"?>
<!--
注意: 除了手动编辑此文件以外,您还可以使用
Web 管理工具来配置应用程序的设置。可以使用 Visual Studio 中的
“网站”->“Asp.Net 配置”选项。
设置和注释的完整列表在
machine.config.comments 中,该文件通常位于
\Windows\Microsoft.Net\Framework\v2.x\Config 中
-->
<configuration>
<configSections />
<connectionStrings>
<add name="TechName" connectionString="莆田九九网络工作室" />
<add name="TechWebsite" connectionString="http://www.99wl.cn" />
</connectionStrings>
<system.web>
<!-- 看这 -->
<httpModules>
<add name="RolesProvider" type="RolesProvider"/>
</httpModules>
<globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8" culture="zh-CN"/>
<!--
设置 compilation debug="true" 可将调试符号插入
已编译的页面中。但由于这会
影响性能,因此只在开发过程中将此值
设置为 true。
-->
<compilation debug="false"/>
<!--
通过 <authentication> 节可以配置 ASP.NET 用来
识别进入用户的
安全身份验证模式。
-->
<authentication mode="Forms">
<forms name="adminsCookieName" protection="All" timeout="720" requireSSL="false" cookieless="UseDeviceProfile"/>
</authentication>
<!--
如果在执行请求的过程中出现未处理的错误,
则通过 <customErrors> 节可以配置相应的处理步骤。具体说来,
开发人员通过该节可以配置
要显示的 html 错误页
以代替错误堆栈跟踪。
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
</system.web>
</configuration>
到这就可以实现自定义伪静态功能了,跟官方UrlRewrite.dll没什么区别,就是少引用dll文件,还有可以把规则写在自己的xml或config文件中,好用xml类去操作管理。IIS6应用没有问题,IIS7+版本HttpModule 暂未学习配置。
第一学堂( www.dyxue.com) 专注于提供网站建设 (Web) 技术文摘,编程开发 ASP.NET/ASP/