Kata Pengantar
Selama Anda memiliki sedikit pemahaman tentang ViewState, Anda akan tahu bahwa ViewState di halaman Asp.net umumnya disimpan di bidang tersembunyi di halaman:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="Banyak hal yang berantakan">
Saat kita menjelajahi file sumber halaman, kita melihat banyak hal yang berantakan (terutama ketika halaman tersebut memiliki DataGrid dengan jumlah data yang besar, atau GridView di ASP.NET 2.0). waktu, yaitu ViewState.
Pengetahuan dasar
Karena ada beberapa perubahan baru dalam mekanisme penyimpanan persistensi ViewState di ASP.NET 2.0, saya akan memperkenalkan secara singkat hal-hal yang relevan.
Di ASP.NET 1.1, hanya mekanisme persistensi dari domain tersembunyi halaman yang disediakan, jadi dalam beberapa kasus, Anda harus berhenti menggunakan ViewState. Bayangkan jika ada puluhan ribu record di DataGrid Anda (jangan berpikir ini tidak normal) Tidak perlu (seseorang pernah mengalaminya). Jika ViewState diaktifkan, apakah Anda yakin server IIS Anda dapat menahannya dan dapatkah jaringan menahannya? Tentu saja, Anda dapat mengubah mekanisme penyimpanan dengan mengganti metode Page.SavePageStateToPersistenceMedium(), namun jangan lupa untuk mengganti Page.LoadPageStateFromPersistenceMedium(), keduanya berpasangan.
Mekanisme persistensi status tampilan default di ASP.NET 2.0 masih mempertahankan informasi status sebagai string berkode Base64 dalam elemen HTML tersembunyi di halaman (elemen dengan atribut type disetel ke "tersembunyi"). Halaman ASP.NET menggunakan objek HiddenFieldPageStatePersister untuk melakukan pekerjaan ini dan instance IStateFormatter untuk membuat serialisasi dan deserialisasi informasi status objek. Atau, untuk klien seluler dengan bandwidth dan sumber daya terbatas, Anda juga dapat menggunakan kelas SessionPageStatePersister untuk menyimpan status tampilan halaman di objek Session di server. Faktanya, hanya ada satu lagi mekanisme persistensi Sesi status halaman di Sesi, bukan di halaman, yang merupakan penghematan bandwidth.
Namun jika Anda ingin memiliki pemahaman yang lebih mendalam tentang mekanisme persistensi ViewState, Anda harus mengetahui tentang kelas abstrak PageStatePersister. Untuk mempertahankan status tampilan pada klien yang tidak dapat mendukung mekanisme persistensi status tampilan yang ada, Anda dapat memperluas kelas PageStatePersister dan memperkenalkan kelas PageStatePersister Anda. tampilan sendiri. Nyatakan metode persistensi, dan Anda dapat menggunakan adaptor halaman untuk mengonfigurasi aplikasi ASP.NET agar menggunakan mekanisme persistensi status tampilan berbeda berdasarkan jenis klien yang dilayani halaman tersebut. Kelas yang berasal dari kelas PageStatePersister harus mengganti metode Simpan abstrak untuk menyimpan status tampilan dan status kontrol dalam media persistensi, dan mengganti metode Muat untuk mengekstrak informasi status. Jika Anda perlu membuat serial status tampilan dan status kontrol menjadi string, Anda dapat menggunakan objek IStateFormatter yang diakses melalui properti StateFormatter. Ini secara efisien membuat serialisasi dan deserialisasi informasi status objek menjadi string yang dikodekan Base64. Anda juga dapat mengganti properti StateFormatter untuk menyediakan mekanisme serialisasi status objek Anda sendiri. Cara melakukannya dijelaskan dalam kode saya.
Bidang tersembunyi
mekanisme persistensi ViewState
tidak akan diperkenalkan. Seperti yang tercantum dalam kata pengantar.
Sesi
hanya perlu mengganti properti PageStatePersister di ASP.NET2.0.
dilindungi menimpa PageStatePersister PageStatePersister
{
mendapatkan
{
kembalikan SessionPageStatePersister(Halaman);
}
}
Jika Anda perlu mengganti kedua metode LoadPageStateFromPersistenceMedium di ASP.NET1.1:
objek penggantian yang dilindungi LoadPageStateFromPersistenceMedium()
{
kembali Sesi["ViewState"];
}
penggantian yang dilindungi batal SavePageStateToPersistenceMedium (objek viewState)
{
Sesi["ViewState"] = viewState;
DaftarHiddenField("__VIEWSTATE", "");
}
Database (contoh saya SQL Server2000)
ada di ASP1.1. Mohon perhatikan garis ungu di bawah ini. Saya tidak tahu apa gunanya. Itu membuat saya tertekan selama beberapa hari . Kode berikut ini hanya disalin dari kode sumber saya. Anda tidak perlu menulisnya seperti ini sama sekali, kecuali yang diperlukan.
penggantian yang dilindungi batal SavePageStateToPersistenceMedium (status objek)
{
string viewStateID = "VIEWSTATE#" + Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
ClientScript.RegisterHiddenField("__VIEWSTATE","");//Harap dicatat
untuk mencoba
{
jika (losFormatter == nol)
{
losFormatter = LosFormatter baru();
}
StringWriter sw = StringWriter baru();
losFormatter.Serialize(sw, negara bagian);
Umum.ViewStateData vsd = ViewStateData baru();
vsd.ViewStateID = viewStateID;
vsd.ViewState = sw.ToString();
da = Akses Data baru();
kesalahan string = da.SaveViewState(vsd);
Respon.Tulis(kesalahan);
}
menangkap (Pengecualian ex)
{
Response.Write(ex.Message);
}
}
objek override yang dilindungi LoadPageStateFromPersistenceMedium()
{
string viewState = string.Kosong;
mencoba
{
jika (losFormatter == nol)
{
losFormatter = LosFormatter baru();
}
string stateID = Halaman.Permintaan["__VIEWSTATE_KEY"].ToString();
da = Akses Data baru();
viewState = da.LoadViewState(stateID);
}
menangkap
{}
mengembalikan losFormatter.Deserialize(viewState);
}
Baris kode ini pada dasarnya OK di ASP2.0. Mengapa ini dasar? Karena baris di atas ClientScript.RegisterHiddenField("__VIEWSTATE","");
apakah ada baris ini atau tidak, di Asp sama .net1.1 Itu mungkin. Saya juga merujuk ke kode orang lain dan menambahkan baris ini. Setelah menambahkan baris ini, hanya ada <input type="hidden" name="__VIEWSTATE" value="" /> tambahan di
halaman.
Ada dua hal sepertiitu
di file sumber halaman setelah dijalankan. Tidak apa-apa untuk menghapus baris itu, jadi saya tidak mengerti untuk apa pernyataan itu digunakan. Tapi itu tidak berfungsi di Asp.net2.0. Ada kesalahan berikut:
Informasi statusuntuk
halaman ini tidak valid dan mungkin rusak.
dan saya tidak dapat menemukan apa pun dengan mencari di Google. , ya, saya tidak tahu apakah kalimat itu salah. Saya telah mengalami depresi selama dua hari dan masalahnya tidak dapat diselesaikan menyimpan status tampilan ke dalam database dan membacanya dari database, saya tidak dapat menemukan kesalahannya, jadi saya memikirkan kodenya berulang kali, tetapi saya sedikit bingung tentang baris itu bidang "__VIEWSTATE", jadi saya mengomentari baris ini, dan itu benar-benar berfungsi. Jadi saya masih tidak mengerti untuk apa baris itu.
Tentu saja, kita juga dapat menyelesaikan fungsi di atas dengan menulis subkelas baru PageStatePersister, yang baru di ASP.NET2.0:
namespace PageAdapter
{
menggunakan Sistem;
menggunakan Sistem.IO;
menggunakan Sistem.Keamanan.Izin;
menggunakan Sistem.Web;
menggunakan System.Web.UI;
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
kelas publik DatabasePageStatePersister : PageStatePersister
{
Public DatabasePageStatePersister(Halaman halaman): basis(halaman)
{}
//
// Muat ViewState dan ControlState.
//
penggantian publik batalkan Load()
{
keadaan tampilan string;
Pemformat IStateFormatter = ini.StateFormatter;
DataAccess da = DataAccess baru();
string stateID = base.Page.Request["__VIEWSTATE_KEY"].ToString();
viewState = da.LoadViewState(stateID);
Pasangkan statePair = (Pasangkan)formatter.Deserialize(viewState);
ViewState = statePair.Pertama;
ControlState = statePair.Second;
}
//
// Pertahankan ViewState dan ControlState apa pun.
//
penggantian publik batal Simpan()
{
jika (ViewState != null || ControlState != null)
{
if (Halaman.Sesi!= null)
{
string viewStateID = "VIEWSTATE#" + base.Page.Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
base.Page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
Pasangkan statePair = Pasangan baru(ViewState, ControlState);
Pemformat IStateFormatter = ini.StateFormatter;
// Membuat serial objek statePair menjadi sebuah string.
string serializedState = formatter.Serialize(statePair);
ViewStateData vsd = ViewStateData baru();
vsd.ViewStateID = viewStateID;
vsd.ViewState = serializedState;
DataAccess da = DataAccess baru();
kesalahan string = da.SaveViewState(vsd);
}
kalau tidak
throw new InvalidOperationException("Sesi diperlukan untuk StreamPageStatePersister.");
}
}
}
}
Kemudian Anda dapat mengganti properti PageStatePersister:
protected override PageStatePersister PageStatePersister
{
mendapatkan
{
kembalikan DatabasePageStatePersister(Halaman);
}
file tersebut
tidak jauh berbeda dengan database. Saya hanya berbicara tentang ASP.NET2.0 Seharusnya serupa di ASP.NET1.1, tetapi saya belum menulis kode untuk debugging:
Saya masih menggunakan metode ini penulisan subkelas baru PageStatePersister :
namespace StreamPageAdapter
{
menggunakan Sistem;
menggunakan Sistem.IO;
menggunakan Sistem.Keamanan.Izin;
menggunakan Sistem.Web;
menggunakan Sistem.Web.UI
;
// StreamPageStatePersister adalah contoh status tampilan
// mekanisme persistensi yang mempertahankan tampilan dan kontrol
// menyatakan di server Web.
//
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
kelas publik StreamPageStatePersister : PageStatePersister
{
publik StreamPageStatePersister(Halaman halaman): dasar(halaman)
{}
//
// Muat ViewState dan ControlState.
//
penggantian publik void Load()
{
Aliran stateStream = GetSecureStream();
// Membaca string status menggunakan StateFormatter.
Pembaca StreamReader = StreamReader baru (stateStream);
Pemformat IStateFormatter = this.StateFormatter;
string fileContents = pembaca.ReadToEnd();
// Deserilize mengembalikan objek Pair yang diserialkan
// metode Simpan.
Pasangkan statePair = (Pasangkan)formatter.Deserialize(fileContents);
ViewState = statePair.Pertama;
ControlState = statePair.Kedua;
pembaca.Tutup();
stateStream.Tutup();
}
//
// Pertahankan ViewState dan ControlState apa pun.
//
penggantian publik batal Simpan()
{
jika (ViewState != null || ControlState != null)
{
if (Halaman.Sesi!= null)
{
Aliran stateStream = GetSecureStream();
Penulis StreamWriter = StreamWriter baru(stateStream);
Pemformat IStateFormatter = this.StateFormatter;
Pair statePair = new Pair(ViewState, ControlState);
// Buat serial objek statePair menjadi sebuah string.
string serializedState = formatter.Serialize(statePair);
penulis.Write(serializedState);
penulis.Tutup();
stateStream.Tutup();
}
kalau tidak
throw new InvalidOperationException("Sesi diperlukan untuk StreamPageStatePersister.");
}
}
// Mengembalikan Aliran aman untuk lingkungan Anda.
Aliran GetSecureStream() pribadi Anda.
{
jalur string = @"d:a.txt";
FileStream fs = FileStream baru(jalur, FileMode.Open, FileAccess.ReadWrite);
kembalikan fs;
}
}
}
Ganti saja properti PageStatePersister:
ganti yang dilindungi PageStatePersister PageStatePersister
{
mendapatkan
{
kembalikan StreamPageStatePersister (Halaman) baru
;
Melalui pengenalan singkat di atas, kita seharusnya memiliki beberapa pemahaman, namun yang perlu kita pahami adalah: di ASP.NET1.1 kita hanya dapat menyelesaikan fungsi di atas dengan menulis ulang age.SavePageStateToPersistenceMedium() dan Page.LoadPageStateFromPersistenceMedium(); .NET1.1 Di ASP.NET2.0, selain itu, kami juga melengkapinya dengan menulis subkelas baru PageStatePersister dan mengganti properti PageStatePersister. Tentu saja, jika Anda membaca konten berikut , Anda akan memahami bahwa menulis subkelas baru PageStatePersister benar-benar berguna.
Menggunakan Adaptor Halaman
Karena mekanisme persistensi status terkait dengan rendering adaptif dan fungsionalitas sisi klien, MyPageAdapter disediakan untuk mengaktifkan DatabasePageStatePersister dari aplikasi ASP.NET. Terakhir, file kemampuan browser (.browser) disediakan untuk mengaktifkan MyPageAdapter untuk kelas klien tertentu (dalam hal ini, browser Web default).
Untuk konten ini, silakan lihat proyek PageAdapter di kode sumber yang saya berikan. Anda akan mengerti setelah membacanya.
menggunakan Sistem.Keamanan.Izin;
menggunakan Sistem.Web;
menggunakan System.Web.UI;
namespace PageAdapter
{
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
kelas publik MyPageAdapter : System.Web.UI.Adapters.PageAdapter
{
penggantian publik PageStatePersister GetStatePersister()
{
kembalikan PageAdapter.DatabasePageStatePersister(Page);
}
}
}
Terakhir, untuk mengaktifkan adaptor MyPageAdapter, Anda harus membuat direktori bernama App_Browsers di direktori root aplikasi ASP.NET dan menyertakan file .browser yang berisi informasi konfigurasi (sebenarnya, ini semua ditambahkan saat Anda menambahkannya ke proyek File .browser akan secara otomatis diselesaikan untuk Anda pada vs2005. Elemen <refID dalam file konfigurasi menunjukkan bahwa konfigurasi mengesampingkan nilai yang ditentukan oleh browser default dalam file konfigurasi Default.browser halaman web .NET. (Tetapi biasanya
adaptor
tidak digunakan).
<browser refID="Bawaan" >
<adaptor kontrol>
< adaptor
controlType="Sistem.Web.UI.Halaman"
adapterType="PageAdapter.MyPageAdapter" />
</controlAdapters>
</peramban>
</browser>
Ini dapat dilihat pada proyek TestPageAdapter di kode sumber. Proyek ini digunakan untuk mendemonstrasikan adaptor halaman.
Kesimpulannya
relatif sederhana, dan mungkin tidak terlalu jelas. Mengenai kelebihan dan kekurangan berbagai mekanisme persistensi, saya belum mengujinya secara spesifik, dan item terakhir "Gunakan adaptor halaman" bukanlah mekanisme persistensi, tetapi menggunakan adaptor. , jadi kita tidak akan mengganti
atribut PageStatePersister. Menurut saya itu tidak terlalu berguna, karena kita dapat menempatkan tindakan mengganti PageStatePersister di kelas dasar halaman, dan semua halaman lain dapat mewarisi kelas dasar ini bagaimana di kode saya. Susah sekali menggunakan adaptor halaman ini. Tentu saja saya tidak tahu banyak tentang adaptor halaman.
Selain itu, penjelasan singkat tentang kode sumber saya:
1. Proyek PageAdapter
DatabasePageStatePersister.cs: subkelas dari kelas PageStatePersister MyPageAdapter.cs: adaptor halaman Akses database DataAccess.cs dan ViewSate.cs, milik kelas tambahan.
2. Proyek StreamPageAdapter
mirip dengan yang di atas, jadi saya tidak akan menjelaskan secara detail.
3. Proyek SaveStateToDatabase
StateInHiddenField.aspx: Uji mekanisme penyimpanan default, yaitu, Anda dapat melihat banyak hal yang berantakan saat Anda melihatnya file sumber halaman.
StateInSession.aspx: Mekanisme penyimpanannya adalah Sesi.
StateInDatabase.aspx: Basis data mekanisme penyimpanannya adalah tipe metode penulisan ulang. Dapat digunakan oleh asp.net1.1 dan 2.0.
StateInDatabase2.aspx: Tulis subkelas baru PageStatePersister dan ganti properti PageStatePersister.
StateInFile.aspx: Simpan ViewState dalam folder di server.
4. Proyek TestPageAdater.
Digunakan untuk pengujian dan adaptor.