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>
//这个规则写的不好,如第一个就可以用一个正则表达式来做。
不管什么样的请求都会先经过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>
//这个规则写的不好,如第一个就可以用一个正则表达式来做。
推荐阅读