Saya menerima email hari ini dan ditanya mengapa UpdatePanel akan menimbulkan masalah jika digabungkan dengan UrlRewrite. Awalnya saya tidak menganggapnya serius, karena saya juga pernah menggunakan UpdatePanel di UrlRewrite sebelumnya, dan tidak ada masalah. Namun setelah menerima kode paket dari pihak lain, saya menemukan bahwa masalah memang terulang kembali. Jika saya mengakses halaman target secara langsung, tidak akan ada masalah. Karena saya berada di perusahaan pada saat itu dan tidak mempelajari dengan cermat penyebab kesalahan tersebut. Dalam perjalanan pulang, saya mensimulasikan proses implementasi UpdatePanel berulang kali di pikiran saya, tetapi saya tidak melihat ada yang salah. Pada akhirnya, saya tidak dapat menahan diri. Saya membuka laptop saya sambil duduk di dalam bus dan dengan hati-hati mencari masalahnya. Busnya bergetar hebat, tapi untungnya saya akhirnya menemukan masalahnya sebelum saya muntah.
Mereproduksi masalahnya:
Sekarang saya akan mereproduksi masalahnya. UrlRewriteModule NBear digunakan dalam kode asli. Demi kesederhanaan, saya menggunakan metode UrlRewrite yang paling umum untuk mendapatkan efek yang sama, mencoba menghindari beberapa teman (termasuk saya) yang tidak akrab dengan NBear dan menghalangi pemahaman artikel. isi.
Pertama, buat Situs Web Baru yang Diaktifkan ASP.NET AJAX. Buat file ~/SubFolder/Target.aspx dengan konten berikut:
~/SubFolder/Target.aspx
<html xmlns=" http://www.w3.org/1999/xhtml " >
<head runat="server">
<title>Halaman Sasaran</title>
</kepala>
<tubuh>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:Manajer Skrip>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Templat Konten>
<%= TanggalWaktu.Sekarang.ToString() %>
<asp:Button ID="Button1" runat="server" Text="Segarkan" />
</Templat Konten>
</asp:Panel Pembaruan>
</bentuk>
</tubuh>
</html>
Kemudian buat Global.asax, sediakan metode Application_BeginRequest, dan implementasikan Url Rewrite di dalamnya, seperti berikut:
Metode Application_BeginRequest di Global.asax
void Application_BeginRequest(pengirim objek, EventArgs e)
{
HttpContext konteks = (pengirim sebagai HttpApplication).Context;
if (konteks.Permintaan.Jalur.Berisi("Sumber.aspx"))
{
konteks.RewritePath("SubFolder/Target.aspx", false);
}
}
Dengan cara ini, ketika kita mengakses file ~/Source.aspx, itu akan ditulis ulang menjadi ~/SubFolder/Target.aspx, buka halamannya, dan semuanya normal:
Setelah mengklik tombol Refresh, waktu diperbarui. Kemudian ketika kita mengklik tombol itu lagi, terjadi kesalahan: "Sys.WebForms.PageRequestManagerServerErrorException: Terjadi kesalahan yang tidak diketahui saat memproses permintaan di server. Kode status yang dikembalikan dari server adalah: 12031".
Analisis masalah:
Alasan untuk masalah ini adalah Url Rewrite memperbarui alamat yang dikirimkan oleh Formulir, dan UpdatePanel mencerminkan perubahan alamat pada halaman.
Saat pertama kali kita membuka halaman tersebut, kita dapat melihat bahwa aksi elemen <form /> pada file sumber halaman tersebut bukan lagi Source.aspx yang kita akses, melainkan file target setelah Url Rewrite:
Aksi elemen formulir adalah halaman target
...
<form name="form1" method="post" action="SubFolder/Target.aspx" id="form1">
...
</bentuk>
...
Untungnya, kami menggunakan Partial Rendering. Selama "target" benar, UpdatePanel masih dapat mengirim dan mendapatkan data dengan benar, lalu memperbarui halaman. Oleh karena itu, setelah mengklik tombol Refresh, halaman diperbarui dengan benar. Namun, tindakan elemen formulir kami juga telah berubah, yang dapat dilihat sekilas menggunakan Web Development Helper dan IE Dev Toolbar:
Karena kita langsung mengakses ~/SubFolder/Target.aspx saat melakukan PostBack asinkron, nilai tindakan dari objek Formulir yang dihasilkan adalah Target.aspx. Hasilnya, UpdatePanel dengan rajin memodifikasi tindakan elemen formulir klien. Ini akan memungkinkan kita untuk mengakses halaman yang tidak ada ketika kita mengirimkannya lagi, dan kesalahan tidak dapat dihindari.
Selesaikan masalahnya:
Sekarang setelah Anda menemukan masalahnya, Anda tentu dapat menyelesaikannya dengan mudah. Kita hanya perlu merespons peristiwa pemuatan Sys.Application. Ini akan dipicu saat halaman dimuat untuk pertama kalinya dan setelah setiap Rendering Parsial. Saat ini, kita dapat mengubah atribut tindakan dari elemen formulir di halaman , sebagai berikut:
Acara pemuatan Sys.Application yang sesuai
Sys.Application.add_load(fungsi()
{
var form = Sys.WebForms.PageRequestManager.getInstance()._form;
form._initialAction = form.action = window.location.href;
});
Adapun mengapa elemen form pada halaman harus diperoleh dengan cara ini, apa itu _initialAction, dan mengapa harus disetel, ini melibatkan implementasi UpdatePanel, jadi saya tidak akan menjelaskannya di sini. Selama sepotong kecil kode ditempatkan pada halaman, masalah ini terpecahkan.
Pertanyaan mendalam:
Alasan untuk masalah ini sebenarnya adalah setelah Url Rewrite, tindakan elemen form bukanlah alamat yang diminta oleh klien, tetapi alamat target Url Rewrite. Jika kita tidak menggunakan Partial Rendering, tetapi menggunakan PostBack paling tradisional, meskipun fungsi halaman tidak akan rusak, setelah PostBack pengguna akan menemukan bahwa konten bilah alamat telah berubah dan langsung menjadi alamat target. Ini bukanlah hasil yang ingin kita lihat. Sekarang sudah ditulis ulang, mari kita tulis ulang sampai akhir. Tentu saja, kita masih dapat menggunakan metode yang disebutkan di atas dan menggunakan JavaScript untuk mengubah tindakan elemen formulir, tetapi metode ini tidak cukup "indah", dan pengguna juga dapat melihat alamat target Penulisan Ulang Url kita dari sumber HTML mengajukan, bukan?
Akan lebih bagus jika kita bisa mengatur tindakan Formulir di sisi server, tapi sayangnya kelas System.Web.UI.HtmlControls.HtmlForm tidak mengizinkan kita melakukan ini. Tapi untungnya, kami menggunakan ASP.NET, dan kami menggunakan model pemrograman berorientasi objek. Jadi kita "mewarisi" System.Web.UI.HtmlControls.HtmlForm dan mengimplementasikan kontrol Form kita sendiri:
mewarisi kelas HtmlForm untuk mengimplementasikan From kita sendiri
namespace Formulir Tanpa Tindakan {
kelas publik Formulir : System.Web.UI.HtmlControls.HtmlForm
{
penggantian yang dilindungi batal RenderAttributes (penulis HtmlTextWriter)
{
writer.WriteAttribute("nama", ini.Nama);
base.Attributes.Remove("nama");
writer.WriteAttribute("metode", ini.Metode);
base.Attributes.Remove("metode");
this.Attributes.Render(penulis);
base.Attributes.Remove("aksi");
jika (base.ID != null)
penulis.WriteAttribute("id", base.ClientID);
}
}
}
Kemudian kita bisa menggunakannya di halaman. Tentu saja, sebelum itu, kita perlu mendaftarkannya di halaman (atau Web.config):
gunakan Formulir yang kita implementasikan sendiri
<%@ Daftar TagPrefix="skm" Namespace="ActionlessForm"
Majelis="Bentuk Tanpa Tindakan" %>
...
<skm:Form id="Form1" metode="post" runat="server">
...
</skm:Formulir>
...
Pada titik ini, kita tidak perlu lagi menulis JavaScript "pintar" di halaman. Masalah tindakan elemen formulir setelah Penulisan Ulang Url telah diselesaikan.
("Pertanyaan mendalam" mengacu pada bagian artikel sebelumnya di MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/urlrewriting.asp )
http://www.cnblogs.com/JeffreyZhao/archive/2006/12/27/updatepanel_with_url_rewrite.html