url重写,一般都是先配置重写规则如:
virtualUrl="^~/(\d+).html"
toUrl = "~/Default.aspx?ID=$1"
这样就能通过访问/100.html重写到实际的default.aspx?id=100的地址。
然后在页面中这样写: <a href="/100.html"> 而不是原先的<a href="default.aspx?id=100">
假如要修改重写的地址,责要修改所有页面的重写链接,以及重写规则。很是麻烦!
--------------问题来了:
上面输出url的两个a瞄,一个是重写的,一个是未重写的实际地址。 如何自动切换,最笨的方法可能用if(重写==true)就输出/100.html,否则是默认的,在每一个a超连接上进行判断输出,这样很累。
能否通过一个方法自动反射出想要的链接呢, 如<a href="<%=getUrl("default.aspx?id=100") %>"> ,这个getUrl(string)的方法去读取规则,反射出virtualUrl地址,这样以后只需要修改重写规则,页面就会自动输出新的规则地址,无需再修改每个页面的超链接。还可以通过判断切换输出,如没开启重写,直接原样返回输出。
想要这个getUrl(string)的方法代码,不要非常详细,大致能实现即可。谢谢
因为getUrl传入的是实际url地址,而在规则里面toUrl的数据不是正则格式,只是匹配格式。这个可能有点难度,还得有点性能。 再谢!
// 我大概的写写,里面关键的集合匹配以及构造虚拟url的代码不知道怎样写了
// 希望高手帮忙. 或提供下其他的思路
public static getUrl(string originalUrl)
{
if(systemIsUrlRewrite)
{
foreach(reurl in reurls)//遍历重写的正则集合
{
if(originalUrl 匹配 reurl.toUrl)
{
return build_virtualUrl(reurl,originalUrl);
//如果集合中有此url的重写规则,就输出此源url的虚拟url,也得用正则吧?
}
}
}
else
{
return originalUrl;//系统没开启url重写,直接返回原始url
}
}
明天.NET 老大, 谢谢你的代码思路,我改写了下, 脑子还有点乱, 现在是完全可以反置那些"正规"的规则了,也就是虚拟url和实际url匹配组要相等. 遇到不相等的恐怕还得加一个循环去折腾. 我觉得在反转替换的时候可以直接在正则遍历时进行,正好减少一个循环. 我再清理下头绪,添加个循环处理"不规则"的规则,应该还是3个循环.
这是我改后的: 恳请斧正
再次修改====改为3个循环, 简单测试支持复杂的规则匹配,不限定规则组次序. 想了想或许只有2个循环也能解决 用到使用只需要解决字符转义了.
protected void Page_Load(object sender, EventArgs e)
{
UrlRewriteRoute test = new UrlRewriteRoute();
//test.VirtualPath = @"~/ 数字(\d+) / 字符(\w+) / 字母([a-zA-Z]*) - 无厘头(.*) \.html";
//test.ToUrl = @"~/1.aspx? 字母=$3 字符=$2 无厘头=$4 数字=$1";
test.VirtualPath = @"~/([a-zA-Z]*)\/(.[0-9]*[a-zA-Z]*)/([0-9]*)/(\w+)/([a-zA-Z]*)\.aspx";
test.ToUrl = @"~/WebPage/$1/$2.aspx?classid=$2;page=$3;keys=$4";
var result = ReverseRoute(test);
Response.Write(test.VirtualPath + "<br/>" + test.ToUrl + "<br/><br/>");
Response.Write(result.VirtualPath + "<br/>" + result.ToUrl + "<br/>");
}
public static UrlRewriteRoute ReverseRoute(UrlRewriteRoute route)
{
UrlRewriteRoute result = new UrlRewriteRoute();
string New_toUrl = route.VirtualPath; //反转定义
string New_virtualUrl = route.ToUrl;
List<string> virtualList = new List<string>();
MatchCollection virtualMatch = Regex.Matches(route.VirtualPath, @"(\(.+?\))");
//先遍历出来转存到List ,List输出内容后倒置成位置索引
foreach (Match m in virtualMatch)
{
virtualList.Add(m.Groups[1].Value);
}
Regex tourlReg = new Regex(@"\$(\d+)");
int i = 1;
foreach (Match m in tourlReg.Matches(route.ToUrl))
{
int GroupNum = Convert.ToInt32(m.Groups[1].Value);
if (virtualList.Count >= GroupNum)
{
New_virtualUrl = New_virtualUrl.Replace(m.Value, string.Format("{0}", virtualList[GroupNum - 1]));
virtualList[GroupNum - 1] = "$"+i.ToString(); //将虚拟Url的索引位置倒置进去 也就是当前索引
i++;
}
}
int k = 0;
foreach (Match matGroup in virtualMatch)
{
//这里的遍历和预存virtualList是一样的,为了能够对应索引位置
//替换相同索引位置的规则匹配组为新的虚拟匹配组位置索引,已经基本支持更复杂的规则匹配
New_toUrl = New_toUrl.Replace(matGroup.Value, virtualList[k]);
k++;
}
result.ToUrl = New_toUrl;
result.VirtualPath = New_virtualUrl; //这里还要解决字符转义问题
return result;
}
public class UrlRewriteRoute
{
public string VirtualPath { get; set; }
public string ToUrl { get; set; }
}