在asp。net2。0中的urlMappings倒是非常好用,可惜暂不支持正则表达式,不过,好在如果用IHttpModule的话
不管什么样的请求都会先经过IHttpModule这样就为URL重写提供了一个好机会:
下面是我写的一个IHttpModule:
usingSystem;
usingSystem。
Web;
publicclassReWriteModule:IHttpModule
{
publicReWriteModule()
{
}
publicoverridestringToString()
{
returnthis。
GetType()。ToString();
}
voidIHttpModule。Dispose()
{
}
privatestaticSystem。
Xml。XmlDocumentruleDoc=null;
privatestaticSystem。Xml。XmlDocumentGetRuleConfig(System。Web。HttpContextapp)
{
if(ruleDoc==null)
{
ruleDoc=newSystem。
Xml。XmlDocument();
ruleDoc。Load(app。Server。MapPath(“~/rule。xml”));
}
returnruleDoc;
}
publicstaticstringGetUrl(System。
Web。HttpContextcxt,stringpath)
{
System。Xml。XmlDocumentdoc=GetRuleConfig(cxt);
System。Xml。XmlNodeListlst=doc。
GetElementsByTagName(“RewriterRule”);
stringpat=””;
foreach(System。Xml。XmlNodendinlst)
{
System。
Xml。XmlNodeListsub=nd。ChildNodes[0]。ChildNodes;
foreach(System。Xml。XmlNodechkinsub)
{
pat=”^”+chk。
InnerText+”$”;
System。Text。RegularExpressions。Regexreg=newSystem。Text。RegularExpressions。Regex(pat,System。Text。
RegularExpressions。RegexOptions。Compiled|System。Text。RegularExpressions。RegexOptions。IgnoreCase);
if(reg。IsMatch(path))
{
returnreg。
Replace(path,nd。ChildNodes[1]。InnerText);
}
}
}
returnnull;
}
voidIHttpModule。
Init(HttpApplicationcontext)
{
context。BeginRequest+=delegate(objectsender,EventArgse)
{
System。
Web。HttpContextcxt=context。Context;
if(cxt。Request。ContentType!=”image/pjpeg”)
{
stringtype=cxt。
Request。ContentType。ToLower();
stringpath=cxt。Request。Path;
stringapppath=cxt。Request。ApplicationPath;
path=path。
Remove(0,apppath。Length);
path=”~”+path;
stringnewUrl=GetUrl(cxt,path。TrimEnd()。TrimStart());
if(newUrl!=null)
{
cxt。
Response。Filter=newResponseFilter(cxt。Response。Filter,cxt。Request。Path);
cxt。Response。Write(“请求的路径:”+path);
cxt。
Response。Write(“<BR>”);
cxt。Response。Write(“转向的目的URL:”+newUrl);
cxt。Response。Write(“<BR>”);
cxt。
RewritePath(newUrl);
}//如果要求处理所有的请求时用到
//else
//{
//cxt。Response。Write(cxt。Request。
Path+”<BR>”);
//cxt。Response。Write(“你请求的资源不存在或无权访问!”);
//cxt。Response。Flush();
//cxt。
Response。End();
//}
}
};
}
}
由于一旦进行了URL重写,原先的WEBFORM中的Action会发生改变,容易造成:请求的资源不存在问题
具体怎么样?各位DX看看就清楚了!
所有才有了这个ResponseFilter了,实现如下。

publicclassResponseFilter:System。IO。Stream
{
publicResponseFilter(System。IO。Streamsink,string_str)
{
_sink=sink;
//
//TODO:在此处添加构造函数逻辑
//
this。
str=_str;
}
privatestringstr=””;
privateSystem。IO。Stream_sink;
privatelong_position;
privateSystem。
Text。Encodingend=System。Text。Encoding。GetEncoding(“GB18030”);
privateSystem。Text。StringBuilderoOutput=newSystem。
Text。StringBuilder();
//ThefollowingmembersofStreammustbeoverriden。
publicoverrideboolCanRead
{
get{returntrue;}
}
publicoverrideboolCanSeek
{
get{returntrue;}
}
publicoverrideboolCanWrite
{
get{returntrue;}
}
publicoverridelongLength
{
get{return0;}
}
publicoverridelongPosition
{
get{return_position;}
set{_position=value;}
}
publicoverridelongSeek(longoffset,System。
IO。SeekOrigindirection)
{
return_sink。Seek(offset,direction);
}
publicoverridevoidSetLength(longlength)
{
_sink。
SetLength(length);
}
publicoverridevoidClose()
{
_sink。Close();
}
publicoverridevoidFlush()
{
_sink。
Flush();
}
publicoverrideintRead(byte[]buffer,intoffset,intcount)
{
return_sink。Read(buffer,offset,count);
}
//TheWritemethodactuallydoesthefiltering。

publicoverridevoidWrite(byte[]buffer,intoffset,intcount)
{
stringszBuffer=System。Text。UTF8Encoding。
UTF8。GetString(buffer,offset,count);
stringap=”action=\””;
intpos=-1;
if((pos=szBuffer。IndexOf(ap))!=-1)
{
intepos=szBuffer。
IndexOf(“\””,pos+ap。Length+1);
if(epos!=-1)
{
szBuffer=szBuffer。Remove(pos+ap。Length,epos-pos-ap。
Length);
}
szBuffer=szBuffer。Insert(pos+ap。Length,this。str);
byte[]data=System。Text。UTF8Encoding。
UTF8。GetBytes(szBuffer);
_sink。Write(data,0,data。Length);
}
else
{
oOutput。
Append(szBuffer);
}
//下面的这一段可以用来修改<Head></head>之间的内容;
//RegexoEndFile=newRegex(“</head>”,RegexOptions。
IgnoreCase|RegexOptions。Compiled);
//if(oEndFile。IsMatch(szBuffer))
//{
////Appendthelastbufferofdata
////附加上缓冲区中的最后一部分数据
//oOutput。
Append(szBuffer);
////Getbackthecompleteresponsefortheclient
////传回完整的客户端返回数据
//stringszCompleteBuffer=oOutput。
ToString()。ToLower();
//intipos=szCompleteBuffer。IndexOf(“<title>”);
//intepos=szCompleteBuffer。
IndexOf(“</title>”,ipos+7);
//stringsp=szCompleteBuffer。Substring(ipos+7,epos-ipos);
//szCompleteBuffer=szCompleteBuffer。
Remove(ipos+7,sp。Length-7);
//szCompleteBuffer=szCompleteBuffer。Insert(ipos+7,”dhz”);
////szCompleteBuffer=szCompleteBuffer。
Replace(sp,”dhz”);
////Nomatch,sowriteoutoriginaldata
////没有匹配,因此写入源代码
//byte[]data=System。
Text。UTF8Encoding。UTF8。GetBytes(szCompleteBuffer);
//_sink。Write(data,0,data。Length);
//}
//else
//{
//oOutput。
Append(szBuffer);
//}
}
}
//////而重候规则呢则是用xml文件配置如下;
当然在web。config通过自定义配置节做也可以的
<xmlversion=”1。
0″encoding=”utf-8″?>
<Rules>
<RewriterRule>
<LookFors>
<LookFor>~/(\d{4})/(\d{2})\。
html</LookFor>
<LookFor>~/(\d{4})/(\d{2})/</LookFor>
<LookFor>~/(\d{4})/(\d{2})</LookFor>
<LookFor>~/(\d{4})/(\d{2})/index。
html</LookFor>
</LookFors>
<SendTo>~/Pro。aspx?year=$1&month=$2</SendTo>
</RewriterRule>
<RewriterRule>
<LookFors>
<LookFor>~/pc</LookFor>
</LookFors>
<SendTo>~/Test2。
aspx</SendTo>
</RewriterRule>
</Rules>
//这个规则写的不好,如第一个就可以用一个正则表达式来做。

相关推荐