欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

asp.net 2.0 中的URL重写以及urlMappings问题

程序员文章站 2023-11-15 12:03:58
在asp.net2.0中的urlmappings倒是非常好用,可惜暂不支持正则表达式,不过,好在如果用ihttpmodule的话  不管什么样的请求都会先经过ih...
在asp.net2.0中的urlmappings倒是非常好用,可惜暂不支持正则表达式,不过,好在如果用ihttpmodule的话 

不管什么样的请求都会先经过ihttpmodule这样就为url重写提供了一个好机会: 

下面是我写的一个ihttpmodule: 

using system; 
using system.web; 

public class rewritemodule:ihttpmodule 

public rewritemodule() 


public override string tostring() 

return this.gettype().tostring(); 



void ihttpmodule.dispose() 



private static system.xml.xmldocument ruledoc = null; 
private static system.xml.xmldocument getruleconfig(system.web.httpcontext app) 

if (ruledoc == null) 

ruledoc = new system.xml.xmldocument(); 
ruledoc.load(app.server.mappath("~/rule.xml")); 

return ruledoc; 

public static string geturl(system.web.httpcontext cxt,string path) 


system.xml.xmldocument doc = getruleconfig(cxt); 
system.xml.xmlnodelist lst= doc.getelementsbytagname("rewriterrule"); 
string pat=""; 
foreach (system.xml.xmlnode nd in lst) 

system.xml.xmlnodelist sub = nd.childnodes[0].childnodes; 
foreach(system.xml.xmlnode chk in sub) 

pat = "^" + chk.innertext+"$"; 
system.text.regularexpressions.regex reg = new system.text.regularexpressions.regex(pat, system.text.regularexpressions.regexoptions.compiled | system.text.regularexpressions.regexoptions.ignorecase); 
if(reg.ismatch(path)) 

return reg.replace(path, nd.childnodes[1].innertext); 



return null; 


void ihttpmodule.init(httpapplication context) 

context.beginrequest += delegate(object sender, eventargs e) 



system.web.httpcontext cxt = context.context; 

if (cxt.request.contenttype != "image/pjpeg") 

string type = cxt.request.contenttype.tolower(); 
string path = cxt.request.path; 
string apppath = cxt.request.applicationpath; 
path = path.remove(0, apppath.length); 
path = "~" + path; 

string newurl = geturl(cxt, path.trimend().trimstart()); 
if (newurl != null) 

cxt.response.filter = new responsefilter(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了,实现如下, 

public class responsefilter:system.io.stream 

public responsefilter(system.io.stream sink,string _str) 

_sink = sink; 
// 
// todo: 在此处添加构造函数逻辑 
// 
this.str = _str; 

private string str = ""; 
private system.io.stream _sink; 
private long _position; 
private system.text.encoding end=system.text.encoding.getencoding("gb18030"); 
private system.text.stringbuilder ooutput = new system.text.stringbuilder(); 
// the following members of stream must be overriden. 
public override bool canread 

get { return true; } 


public override bool canseek 

get { return true; } 


public override bool canwrite 

get { return true; } 


public override long length 

get { return 0; } 


public override long position 

get { return _position; } 
set { _position = value; } 


public override long seek(long offset, system.io.seekorigin direction) 

return _sink.seek(offset, direction); 


public override void setlength(long length) 

_sink.setlength(length); 


public override void close() 

_sink.close(); 


public override void flush() 

_sink.flush(); 


public override int read(byte[] buffer, int offset, int count) 

return _sink.read(buffer, offset, count); 


// the write method actually does the filtering. 
public override void write(byte[] buffer, int offset, int count) 

string szbuffer = system.text.utf8encoding.utf8.getstring(buffer, offset, count); 
string ap="action=\""; 
int pos=-1; 
if ((pos=szbuffer.indexof(ap) )!= -1) 

int epos = 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>之间的内容; 
//regex oendfile = new regex("</head>", regexoptions.ignorecase|regexoptions.compiled); 
//if (oendfile.ismatch(szbuffer)) 
//{ 
// //append the last buffer of data 
// //附加上缓冲区中的最后一部分数据 
// ooutput.append(szbuffer); 
// //get back the complete response for the client 
// //传回完整的客户端返回数据 
// string szcompletebuffer = ooutput.tostring().tolower(); 
// int ipos = szcompletebuffer.indexof("<title>"); 
// int epos = szcompletebuffer.indexof("</title>",ipos+7); 
// string sp = 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"); 
// //no match, so write out original data 
// //没有匹配,因此写入源代码 
// byte[] data = system.text.utf8encoding.utf8.getbytes(szcompletebuffer); 
// _sink.write(data, 0, data.length); 
//} 
//else 
//{ 
// ooutput.append(szbuffer); 
//} 



//////而重候规则呢则是用xml文件配置如下; 

当然在web.config通过自定义配置节做也可以的 

<?xml version="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> 
//这个规则写的不好,如第一个就可以用一个正则表达式来做。