State Management นั้น แบ่งออกเป็น 2 กลุ่มใหญ่ๆครับ คือ Client-side ได้แก่
- Cookies
- Hidden Field
- View State
- Query Strings
- Control state
และ Server-side ได้แก่
- Aplication object
- Session object
- Database
- Transfer method
Cookies
นักพัฒนาเว็บอาจจะรู้จักเจ้าขนมหวานชิ้นนี้มานานแล้วซึ่งเป็นวิธีการส่งค่าแบบ Client-sideโดยจะเอาค่าที่ต้องการไปเก็บอยู่ที่เครื่องของ client ที่รัน browser เลยและค่าของ Cookies จะถูกส่งมาที่ server ทุกครั้ง เมื่อมีการเรียกapplication ใน domain แม้การใช้งาน Cookies จะมีมานานแล้วแต่ก็ยังเป็นที่นิยมอยู่ในปัจจุบัน
ข้อดี คือ ใช้ง่ายครับ และเนื่องจากมันเป็นการเก็บข้อมูลแบบ Client-side ดังนั้น Server จึงไม่ต้องรับภาระตรงนี้ให้เหนื่อยเปล่า
แต่ข้อเสีย คือ เนื่องจากข้อมูลที่เก็บมันอยู่ที่เครื่อง Clientดังนั้นผู้ใช้ฝั่ง Client จึงสามารถแก้ไขดัดแปลงข้อมูลใน Cookiesได้ตลอดเวลา ข้อมูลที่ควรเก็บใน Cookiesจึงไม่ควรเป็นข้อมูลที่สำคัญมากด้วยเหตุผลทางด้านความปลอดภัยครับ
จุดอ่อนอีกอย่างหนึ่งคือ Cookies ไม่สามารถเก็บข้อมูลขนาดใหญ่ได้ โดยที่browser ของแต่ละเจ้าก็มีการจำกัดจำนวน Cookiesในแต่ละโดเมนไม่เท่ากันด้วย เช่น IE6.0 เก็บได้สงสุด 20 Cookiesต่อหนึ่งโดเมน (ค่านี้เปลี่ยนแปลงได้ขึ้นอยู่กับแต่ละเวอร์ชัน)และประการที่สำคัญที่สุดคือเราจะไม่สามารถใช้ Cookies ได้หาก browser ฝั่งclient มีการบล็อคการใช้งาน Cookies เหตุเพราะในอดีต Cookiesถือเป็นอาวุธสำคัญอีกอย่างของบรรดา hacker ทั้งหลายดังนั้นผู้ใช้บางคนจึงไม่อยากเปิดใช้งาน Cookies บน browser สักเท่าไหร่
อย่างไรก็ดีเราสามารถสั่งให้ Cookies ส่งค่าผ่าน SSL (HTTPS) เพียงอย่างเดียวเท่านั้นได้ หากต้องการความปลอดภัยในการใช้งานที่มากขึ้น
ข้อแนะนำอีกประการหนึ่งคือ เราควรเข้ารหัสข้อมูลที่เก็บใน Cookies ด้วยเพื่อป้องกันการเปลี่ยนแปลงข้อมูลโดยตรงจากผู้ใช้
วิธีใช้แสนง่าย
//รับค่าจาก
Cookiesstring value = Request.Cookies["MyValue"].Value;
//กำหนดค่าใน
CookiesResponse.Cookies["MyValue"].Value = "keep value";
//ตรวจสอบวันหมดอายุ
DateTime expire = Request.Cookies["MyValue"].Expires;
//กำหนดวันหมดอายุอีก 30 วันข้างหน้า
Response.Cookies["MyValue"].Expires = DateTime.Now.AddDays(30);
//กำหนดให้หมดอายุทันที
Response.Cookies["MyValue"].Expires = DateTime.Now.AddDays(-1);
Hidden Field เป็น Html Control ตัวหนึ่งนะครับสามารถเซตค่าได้แต่จะไม่ถูก render ที่ browser เท่านั้นเอง
คิดง่ายๆ ก็เหมือน TextBox ที่มองไม่เห็นนั่นแหละครับ ถึงแม้ว่าจะไม่ถูกrender แต่ก็สามารถ view source ดูได้นะครับดังนั้นด้านความปลอดภัยเจ้าตัวนี้ไม่มีเลยนอกจากจะเข้ารหัสให้มันเท่านั้นเองครับ
Hidden Field จะไม่สามารถทำการส่งค่าข้ามเพจได้ ใช้ได้เฉพาะการ postback กลับมาที่หน้าเดิมเท่านั้น
//ประกาศตัวแปร
Hidden FieldSystem.Web.UI.HtmlControls.HtmlInputHidden Hidden1;
//กำหนดค่า
Hidden1.Value = "MyValue";
//รับค่า
string str = Hidden1.Value;
View State เป็น property ที่มีอยู่ในทุก Controlของเพจรวมถึงตัวเพจเองด้วย View State เป็นหัวใจสำคัญของการควบคุม StateValue ใน ASP.NET ซึ่งโดยปกติแล้ว Control ทุกตัวจะทำการเก็บค่า ViewState โดยอัตโนมัติ ทำให้เราสามารถดึงเอาข้อมูลจาก Controlต่างๆหลังจากผู้ใช้ postback มาที่ server โดยไม่ต้องทำอะไรทำให้บรรยากาศในการพัฒนาเว็บคล้ายๆกับการเขียน Windows Application
นอกจากจะเก็บข้อมูลแต่ละ Control แล้ว View Stateของหน้าเพจยังอนุญาตให้เราเก็บอะไรต่อมิอะไรได้ด้วยแม้แต่ objectซึ่งดีกว่า Hidden Field ที่เก็บได้แต่ String โดยค่าต่างๆที่เก็บเข้าไปจะถูกเข้ารหัสและบีบข้อมูลทำให้มีความปลอดภัยเพิ่มขึ้นถึงแม้ข้อมูล ViewState นี้จะถูกส่งไปที่ Client Browser ก็ตาม
เนื่องจาก View Stateเป็น property ของหน้าเพจใดๆ ดังนั้นเราจะไม่สามารถทำการส่งค่า View Stateข้ามเพจได้ ใช้ได้เฉพาะการ postback กลับมาที่หน้าเดิมเท่านั้น
//บันทึกข้อมูล
ViewState["MyValue"] = "MyValue";ViewState["MyTable"] = new DataTable();
//ดึงข้อมูลกลับมา
DataTable tbl = (DataTable)ViewState["MyTable"];
ViewState เก็บค่าลงใน Page ซึ่งจะคล้ายๆกับ HiddenField แต่ ViewStateสามารถเก็บ Object ได้ (แสดงว่าเก็บได้ทุกอย่าง) โดยการ Serialize ข้อมูล
ข้อเสียของ ViewState คือไม่สามารถส่งค่าข้ามฟอร์มได้ เพราะมันจะเก็บลงเฉพาะ Page ตัวเองเท่านั้น
และต้องพึงระวังว่าการโหลดเพจของคุณจะช้าลงเพราะขนาดไฟล์ที่โหลดจะใหญ่ขึ้นครับ
การเก็บค่าไว้ใน ViewState ก็ง่ายนิดเดียว
ViewState["MyInt"] = 10;
ViewState["MyBool"] = true;
ViewState["MyString"] = "Hello World";
ViewState["MyTable"] = new DataTable();
แต่ว่า...ถ้าจะนำออกมาใช้ ก็อย่าลืม Casting ด้วยนะครับ
int a = (int)ViewState["MyInt"];
bool b = (bool)ViewState["MyBool"];
string c = ViewState["MyString"].ToString();
//ใช้แบบนี้ง่ายกว่า Casting ครับ
DataTable table = (DataTable)ViewState["MyTable"];
ถ้าอยากรู้ว่าขนาดของ ViewState เพิ่มขึ้นขนาดไหนก็ไปเปิด Trace ดูได้ครับ
เพิ่มเติมครับ
บางครั้งหากเราเขียน Web Custom Control
มันก็จะมีการใช้คู่กันแบบนี้ครับ
public class MyTextBox : TextBox
{
public string MyName
{
get{ return ViewState[ "MyName" ].ToString(); }
set{ ViewState[ "MyName" ] = value; }
}
/*** ไม่ได้ใช้แบบนี้ เนื่องจาก พอเกิดการ PostBack ค่ามันจะหายครับ****/
private string _name;
public string MyName
{
get{ return name; }
set{ name = value; }
}
}
เวลาเรียกใช้ก็จะเรียกผ่าน Property ชื่อ MyName ครับ
แต่เก็บค่าในแบบ ViewState
Control State คล้ายๆ View state แต่จะต้องเขียน code มากกว่า ซับซ้อนกว่าแต่ข้อดีคือ ไม่สามารถที่จะ disable ได้ ในขณะ View state สามารถถูกdisable ได้ ทำให้ control บางอย่างที่ใช้ View stateเป็นกลไกหลักในการเก็บข้อมูลไม่สามารถใช้งานได้ถูกต้อง
Query Strings เป็นวิธีที่ simple และ classic ที่สุด คือส่งค่าไปกับ urlซึ่งก็มีข้อดีคือความง่าย แต่ต้องแลกมาด้วย security นั่นแหละรวมถึงความยาวด้วย เพราะ browser จำกัดความยาวของ url ไว้
Application State เป็นตัวแปรที่มี scope ในระดับ application แต่ว่าจะมีlifetime จำกัด (volatile state) นั่นคือหาก application มีการ restartใหม่ ตัวแปรนี้จะหายไป และถูกสร้างขึ้นใหม่ด้วย
Session State ใช้งานง่าย ปลอดภัยสูง เก็บข้อมูลได้ทุกชนิด แต่ก็ทำให้server รับภาระมากเหมือนกัน หากเขียนจัดการไม่ดี web จะถูกโจมตีได้ง่ายมาก
Profile Properties ใช้งานคล้ายๆ Session แต่ว่าเก็บแบบถาวรกว่าคือไม่สูญหายไปไหน แม้ application จะถูก restart ก็ตาม แต่การจะใช้profile ได้ ต้องมีการเซ็ตอัพระบบ user อีกมากมาย และก็ทำงานได้ช้ากว่าsession
Database Support ก็เป็นการใช้ DB ในการเก็บข้อมูลนั่นแหละ
Credit: DevStock