ASP.NET URL擬似静的書き換えの実現方法

5252 ワード

Webでconfigには次のように設定されています.
 
  









~/d(\d+)\.aspx
~/default.aspx?id=$1










其中


用于指定配置节"RewriterConfig"的处理程序类的名称为”URLRewriter.Config.RewriterConfigSerializerSectionHandler”,该类存在于bin目录下的URLRewriter .dll文件中
关键的是这两句
~/d(\d+)\.aspx
~/default.aspx?id=$1
~/d(\d+)\.aspx
表示,用户输入的url,d(\d+)\.aspx是 url中文件名匹配的正则表达式(此处为字母d开头,后面跟一个或多个数字,并以.aspx结尾。用户也可根据自己的需要自行设定)。
~/default.aspx?id=$1
,表示当服务器接收到符合上面条件的请求后如何重 写url。此处表示访问defalutl.aspx并传入参数id,其值$1将用用户请求的文件名中的第一个数字来表示。
例如用户输入 hostname/d11.aspx, 服务器会把他重写为http://hostname/default.aspx?id=11。换句话说用户输入http: //hostname/d11.aspx,实际访问的是http://hostname/default.aspx?id=11。这样就起到了隐藏真实文件名,并便于用户记忆的作用。
处理回发
在重写后的url里如果产生回发,例如有一个按钮,又调用了该被重写的aspx,用户浏览器中将会显示该aspx文件实际的地址,也就是http: //hostname/default.aspx?id=11。但从用户的角度考虑,如 果单击按钮时突然看到 URL 更改会使他们感到不安。因此必须解决这个问题。
解决方法有二:
(1)自己定义一个Actionlessform类,在aspx中不再使用系统提供的form 标记
 
  
namespace ActionlessForm
{
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 Webアプリケーションで使用する場合は、まずWebアプリケーションのReferencesフォルダに追加します.次に、HtmlFormクラスの代わりに使用するには、ASP.NET Webページの上部には、次の内容が追加されています.
次に、(ある場合)を次のように置き換えます.
右側のタグを次のように置き換えます.
/******************************************/
以上の方法:ページに作成制御項目にエラーが発生しました.次に、上記を使用しない方法について説明します.
ページを削除します.
(ある場合)を置換し、右側のタグを次のように置換します.
次に、次の方法を実行します.
(2)以上はformを継承し、2つ目の方法はpageを継承することであり、aspxページで何も変更する必要はありません.
コード:
 
  
using System;
using System.IO;
using System.Web;
using System.Web.UI;
namespace URL
{
public class OLPage : Page
{
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);
}}}

このファイルをdllにコンパイルし、あなたのプロジェクトで参照します.
次に、プロジェクト内のすべてのaspxファイルに対応するcsファイルの継承pageクラスのコードを継承OLPageに書き換えます.
たとえば
public class WebForm1:page
に書き換える
public class WebForm1:URL.OLPage
これで再送問題を解決します.
(3)クライアントコードによりformのactionをクリアする.
ASPXページでは、クライアントがコードを表示すると、formにactionが自動的に追加され、アドレスが最初に述べた元のページアドレスであることがわかります.ASPXページでは、actionが空の場合、現在のアドレスに返信されます.これにより,クライアントがactionをクリアする方法により,再送後もアドレスを保持し続けることができる.
ページに次のコードを追加します.
try{document.forms[0].action=""}catch(ex){}
この方法は最も簡単で、元のコードを変更する必要はありません.