มีความจำเป็นต้องรักษาข้อมูลสถานะสำหรับเว็บเพจและส่วนควบคุม อย่างไรก็ตาม เนื่องจากเว็บแอปพลิเคชันถูกสร้างขึ้นบนโปรโตคอล HTTP ซึ่งเป็นโปรโตคอลไร้สัญชาติ การรักษาข้อมูลสถานะจึงกลายเป็นเรื่องยากมาก เพื่อที่จะแก้ไขปัญหานี้ เทคโนโลยี ASP.NET 2.0 มอบโซลูชั่นที่หลากหลาย เช่น การใช้เซสชัน คุกกี้ สถานะการดู สถานะการควบคุม ฟิลด์ที่ซ่อน สตริงการสืบค้น การกำหนดค่าผู้ใช้ส่วนบุคคล (โปรไฟล์) เป็นต้น สำหรับการใช้เทคโนโลยี ASP.NET 2.0 เพื่อสร้างการควบคุมเซิร์ฟเวอร์ การรักษาข้อมูลสถานะก็มีความสำคัญเช่นกัน โซลูชันหลักคือการใช้สถานะการดูและสถานะการควบคุม บทความนี้จะอธิบายความรู้พื้นฐานของสถานะมุมมอง (ViewState) โดยละเอียด และแนะนำวิธีการสมัครสถานะมุมมองผ่านแอปพลิเคชันทั่วไป
ภาพรวมสถานะการดู สถานะ
การดูเป็นเทคโนโลยีที่สำคัญมากที่ช่วยให้เพจและส่วนควบคุมในหน้าสามารถรักษาข้อมูลสถานะระหว่างการเดินทางไปกลับจากเซิร์ฟเวอร์ไปยังไคลเอนต์และกลับจากไคลเอนต์ ด้วยวิธีนี้ คุณสามารถสร้างเอฟเฟกต์เพจแบบมีสถานะและดำเนินการอย่างต่อเนื่องได้บนสภาพแวดล้อมไร้สัญชาติ เช่น เว็บ ในส่วนนี้จะแนะนำกลไกการทำงาน วิธีการสมัคร ประเภทข้อมูลที่จัดเก็บ ประสิทธิภาพและความปลอดภัย การบล็อกสถานะมุมมอง (นี่คือคุณลักษณะใหม่ของ ASP.NET 2.0) ข้อดีและข้อเสียของสถานะมุมมอง
(1)
กระบวนการทำงานเฉพาะของสถานะมุมมองของกลไกการทำงานคือ: เมื่อใดก็ตามที่ผู้ใช้ร้องขอเพจ .aspx เฟรมเวิร์ก .NET จะทำซีเรียลไลซ์ข้อมูลสถานะของส่วนควบคุมที่เกี่ยวข้องเป็นสตริงก่อน จากนั้นทำให้เป็นไฟล์ชื่อ __VIEWSTATE ค่ามูลค่าของฟิลด์ที่ซ่อนอยู่จะถูกส่งไปยังไคลเอนต์ หากมีการร้องขอเพจเป็นครั้งแรก การควบคุมเซิร์ฟเวอร์จะถูกดำเนินการเป็นครั้งแรกเช่นกัน ฟิลด์ที่ซ่อนชื่อ __VIEWSTATE จะมีเฉพาะข้อมูลเริ่มต้นของการควบคุม ซึ่งโดยปกติจะว่างเปล่าหรือเป็นโมฆะ ในเหตุการณ์ postback ที่ตามมา สถานะคุณสมบัติของการควบคุมเซิร์ฟเวอร์ที่มีอยู่ใน postback ก่อนหน้าจะถูกบันทึกใน ViewState ซึ่งช่วยให้การควบคุมเซิร์ฟเวอร์สามารถตรวจสอบสถานะก่อนที่จะเกิดเหตุการณ์ postback ที่ได้รับการจัดการในปัจจุบัน กระบวนการเหล่านี้ได้รับการดูแลโดยกรอบงาน .NET และสำหรับผู้ใช้ การเรียกใช้งานเพจ .aspx จะมีผลต่อการดำเนินการอย่างต่อเนื่อง
(2) ประเภทข้อมูลที่จัดเก็บ
สถานะมุมมองสามารถจัดเก็บข้อมูลได้หลายประเภท และเพื่อปรับปรุงประสิทธิภาพการทำงาน สถานะมุมมองเองยังรวมชุดวิธีการซีเรียลไลซ์ที่ได้รับการปรับปรุงสำหรับประเภททั่วไปด้วย ประเภทข้อมูลที่รองรับโดยวิธีการทำให้เป็นอนุกรมสถานะมุมมองตามค่าเริ่มต้นมีดังนี้: สตริง, Int32, หน่วย, สี, อาร์เรย์, ArrayList, HashTable และตัวแปลงประเภทแบบกำหนดเอง TypeConverter
สถานะมุมมองได้รับการปรับให้เหมาะสมสำหรับออบเจ็กต์ Array, ArrayList และ HashTable ที่มีประเภทที่ระบุไว้ข้างต้น ดังนั้น เมื่อใช้สถานะมุมมองในการควบคุม คุณควรพยายามจำกัดการใช้งานของคุณให้เหลือเพียงประเภทข้อมูลแบบง่ายด้านบน รวมถึงประเภทที่ปรับให้เหมาะสมแล้ว ที่นี่ เราต้องมุ่งเน้นไปที่ตัวแปลงประเภทแบบกำหนดเอง TypeConverter ซึ่งมีวิธีการแบบครบวงจรในการแปลงประเภทค่าเป็นประเภทอื่น และเข้าถึงค่ามาตรฐานและคุณสมบัติย่อย ตัวอย่างเช่น คุณสามารถใช้ TypeConverter เพื่อแปลงสตริงเป็นค่าตัวเลข หรือค่าตัวเลขเป็นสตริง หากไม่มีตัวแปลงชนิด กรอบงานเพจจะใช้ฟังก์ชันการทำให้เป็นอนุกรมแบบไบนารีที่จัดทำโดย .NET Framework เพื่อทำให้วัตถุเป็นอนุกรม กระบวนการนี้ใช้ทรัพยากรมาก
(3) ประสิทธิภาพและความปลอดภัย
เมื่อใช้สถานะมุมมอง อ็อบเจ็กต์จะต้องถูกซีเรียลไลซ์ก่อน จากนั้นจึงดีซีเรียลไลซ์ผ่าน postback ดังนั้นเราจึงต้องรู้บางอย่างเกี่ยวกับประสิทธิภาพของ ViewState ตามค่าเริ่มต้น ViewState ของตัวควบคุมจะถูกเปิดใช้งาน หากคุณไม่จำเป็นต้องใช้ ViewState วิธีที่ดีที่สุดคือปิด ViewState จะไม่จำเป็นอีกต่อไปในสถานการณ์ต่อไปนี้: (1) การควบคุมไม่ได้กำหนดเหตุการณ์ฝั่งเซิร์ฟเวอร์ (เหตุการณ์การควบคุมในขณะนี้คือเหตุการณ์ฝั่งไคลเอ็นต์ทั้งหมดและไม่มีส่วนร่วมใน postback); (2) การควบคุมมี ไม่มีค่าคุณสมบัติไดนามิกหรือข้อมูลที่ถูกผูกไว้ วิธีการปิดสถานะมุมมองคือการตั้งค่า EnableViewState ของตัวควบคุมเป็น "false" นั่นคือ EnableViewState="false"
ตามค่าเริ่มต้น เมื่อเนื้อหาที่เกี่ยวข้องกับสถานะมุมมองถูกรวบรวมและส่งไปยังไคลเอนต์ ผู้อ่านจะเห็นเนื้อหาฟิลด์ที่ซ่อนอยู่ __VIEWSTATE ในโค้ด HTML ของเพจ สิ่งเหล่านี้คือสตริงที่ไม่มีความหมายและเป็นผลมาจากกรอบงาน .NET ที่เข้ารหัสเนื้อหาที่เกี่ยวข้องผ่านการเข้ารหัส Base64 พวกเขาจะถูกส่งไปมาระหว่างไคลเอนต์และเซิร์ฟเวอร์ในรูปแบบข้อความที่ชัดเจน ในบางกรณี เช่น เมื่อมีเนื้อหาที่ละเอียดอ่อน เช่น รหัสผ่าน บัญชี สตริงการเชื่อมต่อ ฯลฯ เกี่ยวข้อง การใช้วิธีเริ่มต้นจะไม่ปลอดภัยอย่างยิ่ง ด้วยเหตุนี้ กรอบงาน .NET จึงจัดให้มีกลไกการรักษาความปลอดภัยสองแบบสำหรับ ViewState:
กลไกการตรวจสอบ:
คุณสามารถสั่งให้กรอบงาน .NET เพิ่มรหัสแฮชต่อท้ายข้อมูล ViewState ได้โดยการตั้งค่าคุณลักษณะ EnableViewStateMAC="true" (รหัสแฮชคือ A ประเภท SHA1 ที่มีความยาว 160 บิต ดังนั้นจึงส่งผลกระทบร้ายแรงต่อประสิทธิภาพการดำเนินการ) เมื่อมีเหตุการณ์ postback เกิดขึ้น รหัสแฮชจะถูกสร้างขึ้นใหม่และจะต้องตรงกับรหัสแฮชเดิม ด้วยวิธีนี้ จึงสามารถตรวจสอบได้อย่างมีประสิทธิภาพว่า ViewState สามารถถูกแก้ไขในระหว่างกระบวนการส่งข้อมูลได้หรือไม่ ตามค่าเริ่มต้น .NET Framework ใช้อัลกอริทึม SHA1 เพื่อสร้างรหัสแฮช ViewState นอกจากนี้ คุณยังสามารถเลือกอัลกอริธึม MD5 ได้ด้วยการตั้งค่า <machineKey> ในไฟล์ machine.config ดังที่แสดงด้านล่าง: <machineKey validation="MD5" /> ประสิทธิภาพของอัลกอริทึม MD5 นั้นดีกว่าอัลกอริทึม SHA1 แต่ก็ไม่ปลอดภัยเพียงพอเช่นกัน
· กลไกการเข้ารหัส
ใช้การเข้ารหัสเพื่อปกป้องค่าข้อมูลจริงในช่อง ViewState ขั้นแรก ต้องตั้งค่า EnableViewStatMAC="true" ตามที่อธิบายไว้ข้างต้น จากนั้น ตั้งค่าประเภทการตรวจสอบ machineKey เป็น 3DES ซึ่งก็คือ <machineKey validationKey="AutoGenerate" decryptionKey="AutoGenerate" validation="3DES" /> ซึ่งสั่งให้ ASP.NET ใช้อัลกอริธึมการเข้ารหัส 3DES เพื่อเข้ารหัสค่า ViewState
(4) View State Blocking
เนื้อหาข้างต้นจะแนะนำความรู้พื้นฐานเกี่ยวกับสถานะมุมมอง อย่างไรก็ตาม ผู้อ่านบางคนอาจสับสน: จะเกิดอะไรขึ้นหากข้อมูลสถานะมุมมองมีขนาดใหญ่มากในบางกรณี สิ่งนี้จะมีผลตามมาโดยไม่ตั้งใจอย่างเห็นได้ชัด ด้วยเหตุนี้ ASP.NET 2.0 จึงเพิ่มคุณลักษณะใหม่ที่เรียกว่า "การบล็อกสถานะมุมมอง" หากปริมาณข้อมูลในสถานะมุมมองมีขนาดใหญ่เกินไป การแบ่งส่วนสถานะมุมมองจะแบ่งข้อมูลออกเป็นหลายส่วนโดยอัตโนมัติ และวางข้อมูลลงในช่องแบบฟอร์มที่ซ่อนอยู่หลายช่อง
หากต้องการเปิดใช้งานการแบ่งสถานะมุมมอง ให้ตั้งค่าคุณสมบัติ MaxPageStateFieldLength เป็นขนาดสูงสุดที่อนุญาตในฟิลด์สถานะมุมมองเดียว หน่วยเป็นไบต์ เมื่อเพจถูกโพสต์กลับไปยังเซิร์ฟเวอร์ เพจจะแยกวิเคราะห์สตริงสถานะมุมมองในระหว่างขั้นตอนการเตรียมใช้งานเพจ และเรียกคืนข้อมูลคุณสมบัติในเพจ การตั้งค่าเริ่มต้นคือ -1 ซึ่งหมายความว่าไม่มีขนาดสูงสุด และสถานะมุมมองจะไม่ถูกแบ่งออกเป็นชิ้นๆ
(5) ข้อดีและข้อเสีย
การใช้สถานะมุมมองมีข้อดีสามประการต่อไปนี้: 1. ใช้ทรัพยากรเซิร์ฟเวอร์น้อยกว่า (เมื่อเทียบกับแอปพลิเคชันและเซสชัน) เนื่องจากข้อมูลสถานะมุมมองถูกเขียนไปยังคอมพิวเตอร์ไคลเอนต์ 2. ดูแลรักษาง่าย ตามค่าเริ่มต้น ระบบ .NET จะเปิดใช้งานการบำรุงรักษาข้อมูลสถานะการควบคุมโดยอัตโนมัติ 3. คุณสมบัติด้านความปลอดภัยที่ได้รับการปรับปรุง ค่าในสถานะมุมมองจะถูกแฮช บีบอัด และเข้ารหัสตามการใช้งาน Unicode ซึ่งมีความปลอดภัยมากกว่าการใช้ฟิลด์ที่ซ่อนอยู่
การใช้สถานะมุมมองมีข้อเสียสามประการต่อไปนี้: 1. ข้อควรพิจารณาด้านประสิทธิภาพ เนื่องจากสถานะการดูถูกจัดเก็บไว้ในเพจ หากจัดเก็บค่าจำนวนมาก ผู้ใช้อาจยังคงช้าลงเมื่อแสดงและส่งเพจ แม้ว่าสถานะการดูจะถูกแบ่งเป็นส่วนก็ตาม 2. ข้อจำกัดของอุปกรณ์ อุปกรณ์เคลื่อนที่อาจมีความจุหน่วยความจำไม่เพียงพอที่จะจัดเก็บข้อมูลสถานะการดูจำนวนมาก ดังนั้น เมื่อย้ายการควบคุมเซิร์ฟเวอร์บนอุปกรณ์ จะมีการใช้วิธีการใช้งานที่แตกต่างออกไป 3. ความเสี่ยงด้านความปลอดภัยที่อาจเกิดขึ้น สถานะการดูถูกจัดเก็บไว้ในฟิลด์ที่ซ่อนอยู่อย่างน้อยหนึ่งฟิลด์บนเพจ แม้ว่าสถานะการดูจะจัดเก็บข้อมูลในรูปแบบแฮช แต่ก็สามารถแก้ไขได้ หากคุณดูแหล่งผลลัพธ์ของหน้าโดยตรง คุณสามารถดูข้อมูลในช่องที่ซ่อนอยู่ ซึ่งนำไปสู่ปัญหาด้านความปลอดภัยที่อาจเกิดขึ้น
การใช้งานทั่วไป
ในกระบวนการพัฒนาการควบคุมเซิร์ฟเวอร์โดยใช้เทคโนโลยี ASP.NET 2.0 มีหลายแง่มุมที่สามารถใช้สถานะมุมมองได้ เป็นเรื่องปกติที่จะใช้พจนานุกรม ViewState เพื่อใช้คุณสมบัติการควบคุมเซิร์ฟเวอร์ ViewState เป็นประเภท System.Web.UI.StateBag - พจนานุกรมของคู่คีย์/ค่าซึ่งสามารถจัดเก็บค่าคุณสมบัติการควบคุมเซิร์ฟเวอร์ได้ ข้อมูลต่อไปนี้ใช้ตัวอย่างทั่วไปเพื่อแสดงวิธีการใช้งาน ViewState
ในตัวควบคุมเซิร์ฟเวอร์แบบกำหนดเอง LabelInViewState จะมีการใช้คุณสมบัติสองอย่าง Text และ TextInViewState อันแรกถูกสร้างขึ้นโดยใช้ตัวแปรส่วนตัว และอันหลังถูกนำไปใช้โดยใช้ ViewState ทั้งหมดนี้ใช้เพื่อรับหรือตั้งค่าเนื้อหาข้อความ ซอร์สโค้ดของไฟล์การใช้งานการควบคุมแบบกำหนดเอง LabelInViewState.cs มีดังนี้
การใช้ระบบ การใช้ System.Collections.Generic; โดยใช้ System.ComponentModel; การใช้ System.Text; ใช้ System.Web; โดยใช้ System.Web.UI; โดยใช้ System.Web.UI.WebControls;namespace WebControlLibrary{ [คุณสมบัติเริ่มต้น("ข้อความ")] [ToolboxData("<{0}:LabelInViewState runat=server"></{0}:LabelInViewState">")] LabelInViewState คลาสสาธารณะ: WebControl { สตริงส่วนตัว _text; // ใช้แอตทริบิวต์ข้อความสตริงสาธารณะ Text { รับ { กลับ (_text == null) ? string.Empty : _text; - ตั้งค่า { _text = ค่า; } - //ใช้ ViewState เพื่อใช้คุณสมบัติ TextInViewState สตริงสาธารณะ TextInViewState { รับ { สตริง s = (สตริง)ViewState["TextInViewState"]; return ((s == null) ? String.Empty : s); - set { ViewState["TextInViewState"] = ค่า; - // แทนที่วิธี RenderContents ป้องกันแทนที่ void RenderContents (เอาต์พุต HtmlTextWriter) { เอาท์พุท เขียน("ข้อความ = "); เอาท์พุท เขียน (ข้อความ); เอาท์พุท เขียน("<br/>"); เอาท์พุท เขียน("TextInViewState = "); เอาท์พุท เขียน (TextInViewState); - - - |
<%@ ภาษาเพจ = "C#" AutoEventWireup = "true" CodeFile = "Default.aspx.cs" สืบทอด = "_Default" % > <%@ ลงทะเบียนเนมสเปซ = "WebControlLibrary" Assembly = "WebControlLibrary" TagPrefix = "ตัวอย่าง" % > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <สคริปต์ runat="เซิร์ฟเวอร์"> เป็นโมฆะ Button1_Click (ผู้ส่งวัตถุ EventArgs e) { demoLabel.Text = กล่องข้อความ1.ข้อความ; demoLabel.TextInViewState = TextBox2.Text; - </สคริปต์>< <html xmlns="http://www.w3.org/1999/xhtml"> <หัว runat="เซิร์ฟเวอร์"> <title>ใช้สถานะมุมมอง ViewState </title> </หัว>< <body style="font-size: small;""> <form id="form1" runat="server"></div> ชื่อ: |
โค้ดด้านบนที่แสดงบนเพจประกอบด้วยกล่องข้อความสองกล่อง สองปุ่ม และตัวควบคุมเซิร์ฟเวอร์แบบกำหนดเอง LabelInViewState ดังที่แสดงในตัวจัดการเหตุการณ์ Button1_Click เมื่อคลิกปุ่ม "ส่ง" ตัวควบคุม LabelInViewState จะได้รับข้อความในกล่องข้อความและแสดงข้อความนั้น การเรนเดอร์แอปพลิเคชันแสดงในรูปที่ 1 และ 2
![]() รูปที่ 1 คลิกปุ่มส่ง | ![]() รูปที่ 2 คลิกปุ่มโหลดซ้ำ |