< rewriter >
< menulis ulang url = " ^/Pengguna/(d+)$ " ke = " ~/Pengguna.aspx?id=$1 " memproses = " berhenti " />
< menulis ulang url = " ^/Pengguna/(w+)$ " ke = " ~/Pengguna.aspx?nama=$1 " memproses = " berhenti " />
</ rewriter >
Saat pengguna meminta "/User/jeffz", kode yang muncul di halaman adalah <form action="/User.aspx?name=jeffz" />. halaman Nilai Request.Url.PathAndQuery saat ini akan digunakan untuk mendapatkan tindakan elemen formulir. Hal ini menyebabkan "User.aspx?name=jeffz" muncul di bilah alamat setelah PostBack, dan alamat ini mungkin tidak dapat meminta sumber daya yang benar (karena mungkin ditulis ulang di tempat lain, atau karena hubungan tingkat direktori) Tidak ada sumber daya tersebut). Pada artikel sebelumnya " UpdatePanel dan UrlRewrite ", saya mengatakan bahwa masalah ini dapat diselesaikan dengan menambahkan sebaris kode JavaScript di akhir halaman:
< script bahasa = "javascript" type = "text/javascript">
document.getElementsByTagName( "formulir" )[0].action = window.location;
</script> Tujuan dari
baris kode ini sangat jelas. Ubah tindakan formulir menjadi window.location (yaitu, jalur di bilah alamat browser), sehingga ketika halaman melakukan PostBack, alamat target akan menjadi. menjadi alamat sebelum Penulisan Ulang URL. Pendekatan ini dapat membuat program berjalan normal, tetapi tidak memuaskan saya. Mengapa?
Karena itu terlalu jelek.
Karena kami masih membeberkan alamat setelah Penulisan Ulang URL ke klien. Selama pengguna menginstal sniffer HTTP (seperti Fiddler yang terkenal), atau langsung memilih untuk melihat file sumber di IE, alamat target kami akan ditampilkan di depan pengguna tanpa penyembunyian apa pun. Bagaimana kami bisa memberi tahu pengguna tentang aturan penulisan ulang kami? Kita harus menyelesaikan masalah ini. Solusinya sangat sederhana dan sudah sangat populer, yaitu dengan menggunakan Control Adapter untuk mengubah perilaku pembuatan Formulir. Namun yang membuat saya merasa aneh adalah semua pencarian Control Adapter ini di Internet adalah versi VB.NET, namun bahasa C# yang terutama dipromosikan oleh Microsoft tidak dapat ditemukan. Meskipun tidak sulit untuk menulis ulang selama Anda memahami sedikit sintaks VB.NET, ini tetap merupakan pekerjaan ekstra. Jadi saya akan posting kode versi C# dari Adaptor ini sekarang agar teman-teman bisa langsung menggunakannya:
namespace Sample.Web.UI.Adapters
{
kelas publik FormRewriterControlAdapter :
Sistem.Web.UI.Adapters.ControlAdapter
{
override yang dilindungi void Render (penulis HtmlTextWriter )
{
base .Render( new RewriteFormHtmlTextWriter (penulis));
}
}
kelas publik RewriteFormHtmlTextWriter : HtmlTextWriter
{
publik RewriteFormHtmlTextWriter (penulis HtmlTextWriter )
: dasar (penulis)
{
ini .InnerWriter = penulis.InnerWriter;
}
public RewriteFormHtmlTextWriter (penulis TextWriter )
: dasar (penulis)
{
ini .InnerWriter = penulis;
}
public override void WriteAttribute (nama string , nilai string , bool fEncode)
{
jika (nama == "tindakan" )
{
Konteks HttpContext = HttpContext .Saat ini;
if (konteks.Item[ "ActionAlreadyWritten" ] == null )
{
nilai = konteks.Permintaan.RawUrl;
konteks.Item[ "ActionAlreadyWritten" ] = true ;
}
}
base .WriteAttribute(nama, nilai, fEncode);
}
}
}
Sederhananya, Adaptor Kontrol ini sebenarnya telah menunggu saat atribut "action" dikeluarkan, dan mengubah nilainya menjadi atribut RawUrl dari objek Permintaan saat ini. Atribut ini ditentukan ketika ASP.NET pertama kali menerima permintaan dari IIS. Atribut ini tidak akan berubah dengan operasi Penulisan Ulang berikutnya di BeginRequest. Oleh karena itu, kita hanya perlu menampilkan tindakan RawUrl untuk Formulir untuk menyelesaikan masalah perubahan alamat PostBack.
Namun, agar Adaptor Kontrol ini dapat diterapkan, Anda juga harus membuat file browser di proyek Web, seperti "App_BrowsersForm.browser", dan menulis kode berikut di dalamnya:
< browser >
< peramban refID = " Bawaan " >
<kontrolAdapter>
< adaptor controlType = " Sistem.Web.UI.HtmlControls.HtmlForm "
adapterType = " Contoh.Web.UI.Adapters.FormRewriterControlAdapter " />
</ kontrolAdapter >
</peramban>
</ browser >
Pada titik ini, masalah perubahan alamat PostBack yang disebabkan oleh Penulisan Ulang URL di level ASP.NET telah diselesaikan dengan sempurna - tunggu, mengapa kita harus menekankan "level ASP.NET"? Benar sekali, karena jika Anda melakukan Penulisan Ulang URL di level IIS, masalah ini masih ada. Misalnya, jika Anda menggunakan IIRF untuk Penulisan Ulang URL dan mengaktifkan Adaptor Kontrol di atas, Anda masih akan menemukan bahwa alamat PostBack pada halaman tersebut berbeda dengan alamat yang diminta oleh klien. Apakah RawUrl juga menjadi "tidak setia"? Hal ini bukan disebabkan oleh RawUrl, namun ditentukan oleh mekanisme ASP.NET. Untuk menjelaskan masalah ini, mari kita lihat kembali diagram di artikel pertama " IIS dan ASP.NET ":
Penulisan ulang URL tingkat IIS terjadi sebelum langkah 2 pada gambar di atas. Karena ditulis ulang, pemilih ISAPI dari IIS akan menyerahkan permintaan ke ASPNET ISAPI untuk diproses. Dengan kata lain, ketika IIS menyerahkan permintaan ke mesin ASP.NET untuk diproses, informasi yang diperoleh ASP.NET dari IIS sudah menjadi alamat setelah Penulisan Ulang URL (misalnya, /User.aspx?name=jeffz), jadi tidak masalah Tidak peduli di mana ASP.NET memproses permintaan, ia tidak dapat mengetahui URL ketika IIS menerima permintaan tersebut.
Dengan kata lain, tidak ada yang bisa kita lakukan untuk mengatasinya.
Namun, empat kata "benar-benar tidak mungkin" bersifat kondisional. Secara lengkap, seharusnya: "mengandalkan ASP.NET itu sendiri" memang "tidak mungkin". Namun bagaimana jika IIS membantu kita saat melakukan Penulisan Ulang URL? Sebagai komponen sumber terbuka yang matang, IIRF secara alami mengetahui bahwa mesin ASP.NET dan bahkan semua penangan ISAPI memerlukan bantuannya. Ia secara alami mengetahui prinsip "buat perubahan saat Anda membuat perubahan", sehingga ia telah belajar menyimpan alamat aslinya. Kemampuan dalam variabel server HTTP_X_REWRITE_URL. Namun, IIRF tidak akan melakukan ini "secara sadar" (betapa melelahkan), jadi kita perlu mengingatkannya di file konfigurasi:
RewriteRule ^/User/(d+)$ /User.aspx?id=$1 [I, L , U ]
RewriteRule ^/User/(w+)$ /User.aspx?name=$1 [I, L, U]
Harap diperhatikan bahwa kami menggunakan Modifier tambahan. Menambahkan U ke koleksi Modifier menunjukkan bahwa kita memerlukan IIRF untuk menyimpan alamat asli sebelum Penulisan Ulang URL di variabel server HTTP_X_REWRITE_URL. Sekarang kita bisa mendapatkan nilai ini di ASP.NET, jadi kita memodifikasi metode WriteAttribute pada kode Adaptor Kontrol sebelumnya sebagai berikut:
public override void WriteAttribute( nama string , nilai string , bool fEncode)
{
jika (nama == "tindakan" )
{
Konteks HttpContext = HttpContext .Saat ini;
if (konteks.Item[ "ActionAlreadyWritten" ] == null )
{
nilai = konteks.Permintaan.ServerVariables[ "HTTP_X_REWRITE_URL" ]
?? konteks.Permintaan.RawUrl;
konteks.Item[ "ActionAlreadyWritten" ] = true ;
}
}
base .WriteAttribute(nama, nilai, fEncode);
}
Sekarang nilai tindakan tidak hanya diperoleh dari atribut RawUrl, tetapi mencoba mendapatkan nilai variabel HTTP_X_REWRITE_URL dari kumpulan ServerVariables, karena alamat permintaan asli yang diterima IIS disimpan di sana.
Pada titik ini, topik utama tentang Penulisan Ulang URL telah dibahas. Pada artikel berikutnya, yang merupakan artikel terakhir dalam seri ini, kami akan fokus pada perbedaan dalam beberapa detail yang disebabkan oleh penggunaan berbagai tingkat Penulisan Ulang URL, dan Poin-poin yang relevan dari Penulisan Ulang URL. catatan.