Archive

Posts Tagged ‘ASP.NET’

View State , ASP.NET State Management

HTTP นั้นเป็น protocol ประเภทที่เรียกว่า stateless  ขึ้น มาแบบนี้ programmer ที่ทำงานด้านนี้ทราบดีอยู่แล้ว แต่สำหรับมือใหม่ หรือเพิ่งเข้ามาจับงานประเภท web base programming ละก็จะต้องทำความเข้าใจกันซะก่อนเป็นเบื่องต้น และเข้าใจมาก ๆ ในเบื้องกลาง และเข้าใจสุด ๆ ในเบื้องปลาย ฮะ ฮะ
Stateless เป็นอย่างไรนะหรือครับลักษณะก็คือ ทุกครั้งที่มีการ request ไปยัง server ( หมายถึง webbrowser นะครับ ) เสร็จแล้วก็จะ disconnect เลยนะครับไม่มีการ คง connection ไว้ เพราะฉะนั้น จะไม่มีการคงอะไรไว้หรือรักษาอะไรไว้เลยระหว่าง สอง connection แบบนี้แหละครับที่เรียกว่า stateless เหตุผลของ architecture นี้ก็คือ เพื่อให้ server สามารถรองรับการ request พร้อม ๆ กัน หลาย ๆ พัน หลาย ๆ หมื่น client โดยที่ไม่เกิด run out of memory นะครับ แต่ปัญหา ของมันก็คือ อืม เราไม่เรียกว่าปัญหา เรียกว่าข้อด้อยของมันดีกว่า ข้อด้อยของมันก็คือ programmer จะต้องหา techniques อื่นเพื่อรักษาข้อมูลระหว่างที่มีการ request และสามารถดึงข้อมูลเหล่านั้นมาใช้งานได้ตามต้องการนั่นเอง

ที่เกรินมาทั้งหมดนี้ก็ เพราะว่า ผมจะหาข้อมูลและเขียนเกี่ยวกับ State Management ในหลาย ๆ ระดับ มาเล่าสู่กันฟัง และก็จะรวมถึง technique การส่งผ่านส่งผ่านข้อมูลจาก page หนึ่งไปยังอีก page ด้วย ดังนั้นในหัวข้อเหล่านี้มันก็คง จะมีหลาย ๆ ตอนอยู่นะครับ ถ้าพลังมีมาก ผมคง ให้รายละเอียดได้ทั้งหมด

View State

View state เห็นจะเป็นหัวข้อแรกที่ผมเลือก ที่จะพูดถึงเพราะ View state นี้เราใช้ในการรักษาข้อมูล ภายใต้กรอบการทำงาน page เดียวเท่านั้น ( ASP.NET web controls ใช้ View State เป็นพื้นฐานอยู่แล้ว ) ซึ่ง View state มันจะทำให้เรารักษาข้อมูลระหว่าง postbacks ได้ ( เหตุการณ์ที่จะทำให้เกิด postback เช่น การ click ปุ่มเป็นต้น )
Page object มี property ที่ชื่อว่า ViewState เป็นตัวช่วยให้เราสามารถที่จะเพิ่มข้อมูลเข้าไปใน View State Collection ได้ และ ข้อมูลที่เราสามารถที่จะเก็บลงใน view state ก็เป็นได้ทั้ง simple data types และ ก็ objects ที่เราสร้างขึ้นมา
ต่อไปเรามาดูการใช้งาน View State กันนะครับ เนื่อง จาก View State นั้นมีรูแบบ ที่เรียกว่า dictionary collection ก็หมายถึงว่าข้อมูลแต่ละตัวจะถูกอ้างอิงด้วย string name ที่แตกต่างกัน เช่น

ViewState[“Counter”] = 1;

นั่นเป็นการ เก็บ 1 ลงใน ViewState Collection และอ้าอิงด้วยชื่อที่มีความหมาย คือ Counter ตรงนี้สำคัญนะครับ ถ้า Counter ยังไม่เคยปรากฏอยู่ใน ViewState collection เลย มันก็จะเพิ่ม Counter เข้าไปและเก็บค่า 1 แต่ถ้า Counter มีอยู่แล้ว มันจะแทนที่ค่าเดิมด้วย 1 นะครับ

การ retrieve ข้อมูล เราก็อ้าอิง ด้วยชื่อ Counter ในลักษณะเดียวกับการ บันทึกข้อมูลงไป ( Counter เราเรียกว่าเป็น Key name ) และเราก็ต้องทำ casting ด้วย data type ที่เหมาะสมนะครับ เพราะการเก็บค่าเข้าเป็นใน View state collection นั้นมักจะถูก ทำให้เป็น object โดยอัตโนมัติ ( กรณีที่พวก simple data type เช่น integer ) ดังนั้นต้อง casting ก่อนเพื่อให้ได้ข้อมูลที่ถูกต้องและนำไปใช้งาน ต่อไปเป็นตัวอย่างของ code แสดงการ retrieve ข้อมูลจาก View State collection

int counter ;
if (ViewState[“Counter”] != null)
{
Counter (int)ViewState[“Counter”];
}

ถ้าเรา พยายามที่จะ retrieve ข้อมูลซึ่งไม่มีเก็บอยู่ใน หรือ ไม่ปรากฏอยู่ ใน Collection เราจะได้ NullReferenceException มาแทน ใน code ก็เลยต้องทำการ ตรวจสอบซะก่อนว่า มีข้อมูลปรากฏอยู่หรือไม่ ถือว่าเป็นหลักปฏิบัติโดยทั่วไป นะครับ
จากตัวอย่างที่ผ่านมา เราสามารถประยุกค์ใช้กับ Data types ชนิดอื่นได้ (Simple data types) นอกจากนี้เรายังสามารถที่จะบันทึก ข้อมูลที่เป็น object ลงใน Veiw State ได้ด้วยเช่นกัน แต่การบันทึกข้อมูล objects ลง View State นั้น Object จะต้องเป็น Object ที่ประกาศให้สามารถ แปลงให้เป็น bytes  stream ได้ หรือ ที่เรียกว่า serialization ครับ การทำก็ไม่ได้เป็นเรื่องยากอะไรครับ แค่เพิ่ม ‘Serializable’ attribute ไว้ที่ การประกาศ class  ดังตัวอย่าง

[Serializable]
public class Student
{
public string firstName;
public string lastName;

public Student(string fName, string lName)
{
firstName = fName;
lastName = lName;
}
}

การเก็บค่าลงใน View State

// Storing a student in view state.
Student stud = new Student(“John”, “Doe”);
ViewState[“CurrentStudent”] = stud;

และการดึงข้อมูลออกมาใช้งาน

// Retrieve a student from view state.
Student stud = (Student) ViewState[“CurrentCustomer”];

อย่าลืมนะครับ เวลาเราดึงข้อมูลจาก View Sate จะต้องทำการ casting ให้เป็น Datatype เดียวกับที่เรา ใส่ลงไปนะครับ ในเรื่อง serializable นั้น มีข้อกำหนดดังนี้นะครับ

  • class จะต้องกำกับด้วย serializable attribute
  • derive ก็จะต้อง เป็น serializable ด้วย
  • ตัวแปร private ของ class ก็จะต้องเป็น serializable หรือ ถ้ามี none serializable ก็จะต้องกำกับ ด้วย [none serializable] attribute

ตัวอย่างการใช้งาน สมมติว่าเราจะทำ PostBack counter ก็คือเราจะทำการเพิ่มค่าทีละ 1 ทุกครั้งที่มีการ click ปุ่มนะครับ ลองมาดูกันว่าเป็นอย่างไร

อันดับแรกเรา สร้าง page ใส่ control ดังต่อไปนี้

และที่ code เป็นอย่างนี้ครับ อันดับแรกเป็นของ Page load event

protected void Page_Load(object sender, System.EventArgs e)
{
//First we check if the page is loaded for the first time,
if (!IsPostBack)
{
ViewState[“PostBackCounter”] = 0;
}
//Now, we assign the variable value in the text box
int counter = (int)ViewState[“PostBackCounter”];
Label1.Text = counter.ToString();
}

ถัดมาเป็น ของ OnClick ของ Button1

protected void Button1_Click(object sender, System.EventArgs e)
{
int oldCount = (int)ViewState[“PostBackCounter”];
int newCount = oldCount + 1;
//First, we assign this new value to the label
Label1.Text = newCount.ToString();
//Secondly, we replace the old value of the view state so that the new value is read the next //time
ViewState[“PostBackCounter”] = newCount;
}

ครับ จาก code จะเห็นว่า ทุกครั้งที่มีการ Click ปุ่ม จะทำการเพิ่มค่าให้ PostBackCounter ทีละหนึ่งนะครับ แต่ครั้งแรกที่ load page นี้จะทำการ set ค่าไปที่ 0
ครับที่กล่าวมาและตัวอย่าง ต่าง ก็คงพอที่จะได้ แนวความคิดการใช้งาน View state บ้าง ไม่มากก็น้อยนะครับ