当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > asp.net 2.0 中的URL重写以及urlMappings问题

ASP.NET
C# Quoted-Printable编码、解码
asp.net Google的translate工具翻译 API
.NET读取所有目录下文件正则匹配文本电子邮件
asp.net 半角全角转化工具
AjaxControlToolKit 显示浏览者本地语言的方法
asp.net HTML文件上传标签
ASP.NET 绑定DataSet中的多个表
ASP.NET 重定向的几种方法小结
Asp.Net 重定向必须要知道的一些资料
ASP.NET 导出到Excel时保留换行的代码
Asp.Net Cache缓存使用代码
document.getElementsByName和document.getElementById 在IE与FF中不同实现
GridView单元格合并
asp.net 大文件上传控件
asp.net 日期函数 某月的第一天和最后一天的日期
asp.net 时间类 一周的周一和周末的日期
C# javaScript函数的相互调用
asp.net membership 密码重设
"虚拟路径"..."映射到另一个应用程序,这是不允许的!
如何传值在2个页面之间 要求不刷新父页面,并且不能用Querystring传值

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-13   浏览: 165 ::
收藏到网摘: n/a

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