在使用了URL重寫的頁面,我們為了保證使用者進行PostBack後頁面的URL仍然是,我們原先展現給使用者的連結,比如是list_1.html而不是list.aspx?page=1
我們需要使用app_browsers目錄,存放瀏覽器定義檔案,相關說明可以參考msdn:http://msdn2.microsoft.com/zh-cn/library/ms228122(vs.80).aspx
<!--可在 <windir>\Microsoft.NET\Framework\<ver>\CONFIG\Browsers 中找到現有的瀏覽器定義--><browsers> <browser refID="Default"> <controlAdapters> <adapter controlType="System.Web.UI.HtmlControls.HtmlForm" adapterType="FormRewriterControlAdapter" /> </controlAdapters> </browser></browsers>
代碼如下:
public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter { protected override void Render(HtmlTextWriter writer) { if (HttpContext.Current.Request.RawUrl.Contains(".html")) { base.Render(new RewriteFormHtmlTextWriter(writer)); } else { base.Render(writer); } } } public class RewriteFormHtmlTextWriter : HtmlTextWriter { public RewriteFormHtmlTextWriter(Html32TextWriter writer) : base(writer) { this.InnerWriter = writer.InnerWriter; } public RewriteFormHtmlTextWriter(System.IO.TextWriter writer) : base(writer) { this.InnerWriter = writer; } public override void WriteAttribute(string name, string value, bool fEncode) { if (name == "action") { if (HttpContext.Current.Items["ActionAlreadyWritten"] == null) { value = HttpContext.Current.Request.RawUrl; HttpContext.Current.Items["ActionAlreadyWritten"] = true; } } base.WriteAttribute(name, value, fEncode); } }以上代碼一直運行了很長時間,但是後來在使用asp.net Ajax是發現URL重寫後的頁面會出現錯誤,重新修改代碼,排除Asp.net Ajax請求進行處理,代碼如下:
public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter { protected override void Render(HtmlTextWriter writer) { if (HttpContext.Current.Request.RawUrl.Contains(".html")) { //取得asp.net Ajax請求標誌 var AsyncPost=HttpContext.Current.Request.Form["__ASYNCPOST"]; if (AsyncPost=="true") //判斷是否asp.net Ajax請求 { base.Render(writer); } else { base.Render(new RewriteFormHtmlTextWriter(writer)); } } else { base.Render(writer); } } } public class RewriteFormHtmlTextWriter : HtmlTextWriter { public RewriteFormHtmlTextWriter(Html32TextWriter writer) : base(writer) { this.InnerWriter = writer.InnerWriter; } public RewriteFormHtmlTextWriter(System.IO.TextWriter writer) : base(writer) { this.InnerWriter = writer; } public override void WriteAttribute(string name, string value, bool fEncode) { if (name == "action") { if (HttpContext.Current.Items["ActionAlreadyWritten"] == null) { value = HttpContext.Current.Request.RawUrl; HttpContext.Current.Items["ActionAlreadyWritten"] = true; } } base.WriteAttribute(name, value, fEncode); } }後又經過調試發現是RewriteFormHtmlTextWriter的構造器有問題,沒有包含htmlTextWriter類型的構造器,而使用了TextWriter類型構造器,導致頁面結構錯誤出現null報錯。再次調整代碼如下:
public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter { protected override void Render(HtmlTextWriter writer) { if (HttpContext.Current.Request.RawUrl.Contains(".html")) { //使用過濾掉asp.net Ajax請求的方式避免錯誤 //而後發現是RewriteFormHtmlTextWriter的構造器的問題,遂放棄方法 //var AsyncPost=HttpContext.Current.Request.Form["__ASYNCPOST"]; //if (AsyncPost=="true") //{ // base.Render(writer); //} //else //{ // base.Render(new RewriteFormHtmlTextWriter(writer)); //} base.Render(new RewriteFormHtmlTextWriter(writer)); } else { base.Render(writer); } } } public class RewriteFormHtmlTextWriter : HtmlTextWriter { //使用html 4.0方式的渲染器 public RewriteFormHtmlTextWriter(HtmlTextWriter writer) : base(writer) { this.InnerWriter = writer.InnerWriter; } //使用html 3.2方式的渲染器,相容老瀏覽器 public RewriteFormHtmlTextWriter(Html32TextWriter writer) : base(writer) { this.InnerWriter = writer.InnerWriter; } //其他方式瀏覽器,有可能引起null錯誤 public RewriteFormHtmlTextWriter(System.IO.TextWriter writer) : base(writer) { this.InnerWriter = writer; } public override void WriteAttribute(string name, string value, bool fEncode) { if (name == "action") { if (HttpContext.Current.Items["ActionAlreadyWritten"] == null) { value = HttpContext.Current.Request.RawUrl; HttpContext.Current.Items["ActionAlreadyWritten"] = true; } } base.WriteAttribute(name, value, fEncode); } }
關於HtmlTextWriter和Html32TextWriter可以看一下這篇文章 http://www.cnblogs.com/Vegaslee/archive/2007/12/04/982723.html