使用微软提供的url重写组件urlrewirter可以很轻松的实现URL重写,方法简单如下:
- 下载urlwriter组件:http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx,将该组件方到web application的bin文件夹下。
- 配置web.config文件:
<? xml version="1.0" encoding="utf-8" ?>
< configuration >
< configSections >
< section name ="RewriterConfig" type ="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
</ configSections >
< RewriterConfig >
< Rules >
< RewriterRule >
< LookFor > ~/d(d+).aspx </ LookFor >
< SendTo > ~/default.aspx?id=$1 </ SendTo >
</ RewriterRule >
</ Rules >
</ RewriterConfig >
< system .web >
< httpHandlers >
< add verb ="*" path ="*.aspx" type ="URLRewriter.RewriterFactoryHandler, URLRewriter" />
</ httpHandlers >
</ system.web >
</ configuration >
其中<section name="RewriterConfig"type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
是表示config文件中配置节RewriterConfig的处理程序URLRewriter.Config.RewriterConfigSerializerSectionHandler,该处理程序在程序集URLRewriter中.配置节UrlRewriterConfig配置节就是请求的URL和实际URL的映射,且支持正则表达式,使用更方便。
但是会遇到这样的问题:当你请求一个URL(如:http://localhost/guangboo/d23.aspx)时, 会被重放到http://localhost/guangboo/default.aspx?id=23 去,但是在该页面点击某一按钮或触发回发事件时候,页面就会被回发到http://localhost/guangboo/default.aspx?id=23 页面,这样实际的URL还是被暴露了,就失去了URL重写的意义了,当我们用记事本打开查看http://localhost/guangboo/d23.aspx页面时,我们会发现,form的action属性是default.aspx,这就是原因所在,网上有这样两种方法可以解决这样的问题,也都是从form 的action属性为出发点的:
1,自己定义一个Actionlessform类,在aspx中不再使用系统提供的form 标记
... {
public class Form : System.Web.UI.HtmlControls.HtmlForm
...{
protected override void RenderAttributes(HtmlTextWriter writer)
...{
writer.WriteAttribute("name", this.Name);
base.Attributes.Remove("name");
writer.WriteAttribute("method", this.Method);
base.Attributes.Remove("method");
this.Attributes.Render(writer);
base.Attributes.Remove("action");
if (base.ID != null)
writer.WriteAttribute("id", base.ClientID);
}
}
}
做用法法是在 ASP.NET 网页的顶部添加以下内容: <%@ Register TagPrefix="skm" Namespace="ActionlessForm" Assembly="ActionlessForm" %> 然后,<form runat="server">(如果有)替换为:<skm:Form id="Form1" method="post" runat="server">
并将右边的 </form> 标记替换为:</skm:Form>
(2)第二种方法就是继承page,这样你不需要在aspx页中改任何东西。
代码
public OLPage() ...{ }
protected override void Render(HtmlTextWriter writer) ...{
if (writer is System.Web.UI.Html32TextWriter) ...{
writer = new FormFixerHtml32TextWriter(writer.InnerWriter);
} else ...{
writer = new FormFixerHtmlTextWriter(writer.InnerWriter);
}
base.Render(writer);
}
}
internal class FormFixerHtml32TextWriter : System.Web.UI.Html32TextWriter ... {
private string _url; // 假的URL
internal FormFixerHtml32TextWriter(TextWriter writer)
: base(writer) ...{
_url = HttpContext.Current.Request.RawUrl;
}
public override void WriteAttribute(string name, string value, bool encode) ...{
if (_url != null && string.Compare(name, "action", true) == 0) ...{
value = _url;
}
base.WriteAttribute(name, value, encode);
}
}
internal class FormFixerHtmlTextWriter : System.Web.UI.HtmlTextWriter ... {
private string _url;
internal FormFixerHtmlTextWriter(TextWriter writer)
: base(writer) ...{
_url = HttpContext.Current.Request.RawUrl;
}
public override void WriteAttribute(string name, string value, bool encode) ...{
if (_url != null && string.Compare(name, "action", true) == 0) ...{
value = _url;
}
base.WriteAttribute(name, value, encode);
}
}
然后把项目中的所有aspx文件对应的cs文件中的继承page类的代码改写为继承OLPage。
例如
public class WebForm1:page
改写为
public class WebForm1:OLPage即可。
但是,我想用http://localhost/guangboo/?a=23 重写到http://localhost/guangboo/Article.aspx?cc=23 的时候又出现问题了,如果用上面的方法来实现这个的话,当在http://localhost/guangboo/?a=23页面产生回发事件时,就会重发到http://localhost/guangboo/default.aspx?a=23;因为默认/?代表了/default.aspx?就是请求http://locahost/guangboo/ 时候就是请求http://localhost/guangboo/default.aspx 一样。同样用记事本打开http://localhost/guangboo/?a=23 可以看到form 的action属性是default.aspx?a=23,只要对上面的OLPage 类稍加修改就可以到目的了,即将OLPage类中的HttpContext.Current.Request.RawUrl改为HttpContext.Current.Request.RawUrl.Replace("default.aspx","");即可。也就是把action中的default.aspx去掉。
改好后,运行又来了一个问题,网页什么内容都没了,除了EnableViewState="true"的控件内容外。将控件的EnableViewState属性设为true ,OK!
注意:我们知道EnableViewState属性用用来保存控件的信息的,在HTML文件中表现为一个<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTIwMDIzMDY0MjcPZBYCZg9kFgICAw9kFgYCBQ8WAh4LX......"/>的隐藏元素,EnableViewState会使页面的大小膨胀很多。因此期待更好的方法。