State Handling
ဒီေန႔ ကြၽန္ေတာ္တို႔ ASP.NET မွာ အေရးၾကီးတဲ႔ state handling အပိုင္းကို ေျပာၾကရေအာင္။ asp.net မွာ server နဲ႔ client ဆိုျပီး အလုပ္လုပ္တာကို ကြၽန္ေတာ္တို႔ သိျပီးသားေနာ္။ browser ကေန request လုပ္လိုက္တဲ႔ အခါမွ web server ထဲကိုသြားျပီး အလုပ္လုပ္တာေလ၊ variable ေတြ ေၾကျငာတာေတြ ရွိမယ္၊ class ေတြ object ေဆာက္မယ္၊ စသည္ျဖင့္ေပါ့။ ဟုတ္ျပီ အဲ့ဒီလို web server ထဲမွာ client request ေပၚမူတည္ျပီး process လုပ္လို႔ ျပီးရင္ client ဆီကို response ျပန္ပို႔ေပးတယ္။ အဲ့ဒီလို request ကို response လုပ္ျပီးတာနဲ႔ web server ထဲမွာ ေဆာက္ထားသမွ်ကို အားလံုး ရွင္းလိုက္ပါတယ္။ ဒါဆို ေနာက္ထပ္တစ္ၾကိမ္ server ကို request ျပန္လာရင္၊ ပထမတစ္ၾကိမ္တုန္းက ေဆာက္ထားသမွ်ေတြ ရွိဦးမလား? မရွိေတာ့ပါဘူး။ ဒုတိယ request အတြက္ ေနာက္ထပ္တစ္ၾကိမ္ ထပ္ျပီး object ေတြ variable ေတြ ျပန္ေၾကျငာရျပန္ပါတယ္။ response ျပီးရင္ ျပန္ဖ်က္လိုက္ျပန္ပါတယ္။ ဒီနည္းအားျဖင့္ request လာတိုင္း လာတိုင္း variable ေတြက အျမဲပဲ အသစ္အသစ္ေတြ ျဖစ္ေနတာပါ။ ဒါဆိုရင္ ပထမတစ္ၾကိမ္တုန္းက variable ထဲမွာ သိမ္းထားခဲ႔တဲ႔ value ေတြကို၊ ဒုတိယ အၾကိမ္မွာ ျပန္ေခၚမယ္ဆိုရင္ ရပါဦးမလား? မရနိုင္ေတာ့ပါဘူး။ ဒီအခ်က္က အေရးၾကီးပါတယ္။ ကြၽန္ေတာ္တို႔ variable ေတြမွာ တန္ဖိုးေတြ သိမ္းတယ္ဆိုတာ အဲ့ဒီ variable က memory ေပၚမွာ ရွိေနသေရႊ႕ပဲ သိမ္းထားလို႔ ရတာပါ။ window form application မွာ အဲ့ဒီ form(class) မွာ ေၾကျငာထားတဲ႔ variable ေတြက အဲ့ဒီ form မပိတ္မျခင္း life time ရွိပါတယ္။ web form application(asp.net) မွာေတာ့ variable တစ္ခုရဲ႕ သတ္တမ္းက request နဲ႔ response ၾကားထဲမွာပဲ ရွိပါတယ္။ ဥပမာဗ်ာ ကြၽန္ေတာ္က number အတိုးအေလွ်ာ့ လုပ္တဲ႔ program ေလး တစ္ခုေရးျပမယ္။

design
inc button ကိုႏွိပ္ရင္ label ထဲက value ကို ၁ တိုးမယ္။ dec ဆိုရင္ ၁ ေလွ်ာ့မယ္ေပါ့။ အိုေက ဒီ ပုစာၦေလးကို ကြၽန္ေတာ္တို႔ window application မွာ ေရးသလိုပဲ ေရးၾကည့္မယ္ဆိုရင္၊ ဒီလိုမ်ိဳး ေရးပါမယ္…
public partial class state_handling : System.Web.UI.Page
{
int value = 0;
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = value.ToString();
}
protected void Button1_Click(object sender, EventArgs e)
{
value++;
Label1.Text = value.ToString();
}
protected void Button2_Click(object sender, EventArgs e)
{
value--;
Label1.Text = value.ToString();
}
}
ေရးထားတာကို ၾကည့္မယ္ဆိုရင္ေတာ့ အားလံုး မွန္တယ္လို႔ ထင္စရာပါပဲ။ ဒါေပမယ့္ run ျပီး button ေတြကို ႏွိပ္ၾကည့္လိုက္ပါဦး။ inc button ကိုႏွိပ္တိုင္း 1 ပဲ ျပေနျပီး၊ dec button ကိုႏွိပ္ရင္ေတာ့ အျမဲပဲ -1 ျဖစ္ေနပါလိမ့္မယ္။ ဘာလို႔ ဒီလို ျဖစ္ရတာလဲ? ဟုတ္ကဲ႔ ကြၽန္ေတာ္တို႔ ေၾကျငာထားတဲ႔ class variable ေၾကာင့္ပါပဲ။ button ႏွိပ္လို႔ server side ကို ျပန္လာတိုင္း ဒီ variable ကို အသစ္ျပန္ျပီး ေၾကျငာပါတယ္။ ဒါေၾကာင့္ အျမဲတမ္း 0 ျပန္ျပန္ျဖစ္သြားတာေၾကာင့္ပါ။ ဟုတ္ကဲ႔ ဒါဆိုရင္ ကြၽန္ေတာ္တို႔ variable ထဲကတန္ဖိုး မေပ်ာက္ေအာင္ ဘယ္လိုသိမ္းမလဲ? State Variable ေတြ အျဖစ္ေၾကျငာျပီး သိမ္းရပါမယ္။ state variable အမ်ိဳးအစား ၃ မ်ိဳးရွိပါတယ္။
- ViewState
- Session
- Application
1) ViewState
Web page တစ္ခုအတြင္းထဲမွာ တန္ဖိုး မေပ်ာက္ေအာင္ သိမ္းခ်င္ျပီဆိုရင္ ကြၽန္ေတာ္တို႔ ViewState variable အျဖစ္ေၾကျငာျပီး သိမ္းလို႔ရပါတယ္။ ViewState variable ေၾကျငာတယ္ဆိုတာက တကယ္ေတာ့ ViewState array ထဲမွာ ေနရာ တစ္ေနရာ သြားယူလိုက္တာပါပဲ။ ကဲ ဒီ program ေလးကို ျပန္ျပင္ျပီး run ၾကည့္ရေအာင္။
public partial class state_handling : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["value"] == null)
ViewState["value"] = 0;
Label1.Text = ViewState["value"].ToString();
}
protected void Button1_Click(object sender, EventArgs e)
{
ViewState["value"] = Convert.ToInt32(ViewState["value"]) + 1;
Label1.Text = ViewState["value"].ToString();
}
protected void Button2_Click(object sender, EventArgs e)
{
ViewState["value"] = Convert.ToInt32(ViewState["value"]) - 1;
Label1.Text = ViewState["value"].ToString();
}
}
အရင္ဆံုး pageload event မွာ ViewState variable ေၾကျငာပါတယ္။ မေၾကျငာခင္မွာ အဲ့ဒီ variable ရွိမရွိ အရင္ စစ္ပါတယ္။ state variable ေတြက object type ပါ။ ဒါေၾကာင့္ null နဲ႔ ညီေနရင္ မေၾကျငာရေသးပါဘူး။ ဒါေၾကာင့္ ကြၽန္ေတာ္က viewstate array ထဲကို တန္ဖိုုးတစ္ခု ထည့္လိုက္ပါတယ္။ ဒါဟာ variable ေၾကျငာ လိုက္တာပါပဲ။ variable name ကို ကြၽန္ေတာ္တို႔ ၾကိဳက္တာ ေပးလို႔ရပါတယ္။ အခုကြၽန္ေတာ္က value လို႔ ေပးလိုက္ပါတယ္။ inc button ႏွိပ္ရင္ အဲ့ဒီ viewstate variable ထဲကတန္ဖိုးကို ၁ တိုးပါတယ္။ ျပီးအဲ့ဒီ variable ကို label မွာ ရိုက္ျပလိုက္တာပါပဲ။ dec button အတြက္လည္း ဒီအတိုင္းပါပဲ။ viewstate variable ကို သံုးျခင္းအားျဖင့္ ကြၽန္ေတာ္တို႔ form တစ္ခုထဲမွာ တန္ဖိုးမေပ်ာက္ေအာင္ သိမ္းလို႔ ရသြားပါျပီ။
2) Session
ကြၽန္ေတာ္တို႔ viewstate variable ထဲက တန္ဖိုးကို page တခုထဲမွာ သိမ္းထားနိုင္ပါတယ္။ ဒါေပမယ့္ ဒီpage ကေန တျခား page တခုကို သြားလိုက္ျပီဆိုတာနဲ႔ အဲ့ဒီ viewstate variable ထဲကတန္ဖိုး မရွိေတာ့ပါဘူး။ ဒါဆို ကြၽန္ေတာ္က Project ထဲမွာ ရွိတဲ႔ ဘယ္page ကိုသြားသြား တန္ဖိုးမေပ်ာက္ေစခ်င္ဘူး ဆိုရင္ေတာ့ viewstate variable ကို သံုးလို႔ မရေတာ့ပါဘူး။ ဒီလို အခ်ိန္မ်ိဳးမွာ Session variable ကိုသံုးရပါမယ္။ ဥပမာဗ်ာ.. အခုကြၽန္ေတာ္တို႔ ေရးေနတာ default.aspx ဆိုပါေတာ့။ အဲ့ဒီမွာ button တစ္ခုထပ္ထည့္ပါမယ္။ go to page2 ေပါ့။ အဲ့ဒီ button click event မွာ ဒီလိုေရးရပါမယ္။
protected void Button3_Click(object sender, EventArgs e)
{
Response.Redirect("Default2.aspx");
}
Response.Redired function က server side မွာ page တခုကေန ေနာက္တစ္ခုကို သြားဖို႔အတြက္ ေရးတာပါ။ အခုကြၽန္ေတာ္က Default2.aspx page ကိုသြားမယ္ေပါ့။ အရင္ဆံုး Defautl2.aspx page ကိုလည္း ေဆာက္ေပးထားဦးေနာ္။ အဲ့ဒီ page ထဲမွာလည္း Default.aspx ကိုျပန္သြားဖို႔အတြက္ ေပၚကလိုပဲ button ေလးထည့္ျပီး event ေရးေပးထားေပါ့။ ျပီးရင္ program ကို ျပန္စမ္းၾကည့္ပါဦး။ Default.aspx ထဲမွာ inc button ကို ၅ ခါႏွိပ္လိုက္မယ္။ ဒါဆို ၅ လို႔ ေပၚေနျပီေပါ့၊ အဲ့ဒီ အခ်ိန္မွာ go to page2 button ကိုႏွိပ္လိုက္၊ Defaut2.aspx ကိုေရာက္သြားမယ္။ go to page1 button ကိုျပန္ႏွိပ္လိုက္၊ ဒါဆို Default.aspx page ကိုျပန္ေရာက္လာျပီ။ အခုၾကည့္လိုက္ပါဦ။ ခုနတုန္းက ေရာက္လက္စ ၅ ေပၚေနေသးလား မေပၚေတာ့ဘူးေနာ္။ 0 ကေန ျပန္စသြားတာကို ေတြ႔ရပါလိမ့္မယ္။ ဒါကို ေျပာခ်င္တာပါ၊ viewstate variable ေတြက page တစ္ခုအတြင္းမွာပဲ တန္ဖိုးမေပ်ာက္ေအာင္ သိမ္းနိုင္ပါတယ္။ အိုေက အခုကြၽန္ေတာ္ Session variable နဲ႔ ေျပာင္းျပီး ျပန္စမ္းၾကည့္ပါဦး။
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Session["value"] == null)
Session["value"] = 0;
Label1.Text = Session["value"].ToString();
}
protected void Button1_Click(object sender, EventArgs e)
{
Session["value"] = Convert.ToInt32(Session["value"]) + 1;
Label1.Text = Session["value"].ToString();
}
protected void Button2_Click(object sender, EventArgs e)
{
Session["value"] = Convert.ToInt32(Session["value"]) - 1;
Label1.Text = Session["value"].ToString();
}
protected void Button3_Click(object sender, EventArgs e)
{
Response.Redirect("Default2.aspx");
}
}
3) Application
Session variable က user ကို ကိုယ္စားျပဳပါတယ္။ user တစ္ေယာက္ကို session တစ္ခုေပါ့။ ဒါဆို user ဆိုတာကေရာ ဘာကိုေျပာတာလဲ? User ဆိုတာက client ကြန္ပ်ဴတာရဲ႕ browser ကို ရည္ညႊန္းပါတယ္။ ဥပမာ.. ကြၽန္ေတာ္အခု ေရးထားတဲ႔ inc-dec program ကို client computer ၃ လံုးကေန ေခၚသံုးမယ္ ဆိုပါေတာ့။ client A က inc လုပ္တယ္၊ ၃ အထိေရာက္ေနျပီ။ အဲ့ဒီ အခ်ိန္မွာ client B က ၀င္လာတယ္၊ inc button ကိုႏွိပ္တယ္၊ ၄ ကေနစေပၚမလား? မေပၚပါဘူး။ ၁ ကေနပဲ စျပီး ေပၚမွာပါ။ ဆိုလိုတာကေတာ့ client A နဲ႔ client B က ဘာမွ မဆိုင္တဲ႔ သီးျခား user(session) ေတြျဖစ္လိုပါပဲ။ တခါတေလမွာ ကြၽန္ေတာ္တို႔က session အားလံုးနဲ႔ ဆိုင္တဲ႔ variable မ်ိဳး လိုခ်င္ျပီဆိုရင္ေတာ့ Session variable နဲ႔လည္း အဆင္မေျပေတာ့ပါဘူး။ ဒီအခါမ်ိဳးမွာ application variable ကို သံုးလို႔ ရပါတယ္။ ဒီလိုမ်ိဳးပါ…
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Application["value"] == null)
Application["value"] = 0;
Label1.Text = Application["value"].ToString();
}
protected void Button1_Click(object sender, EventArgs e)
{
Application["value"] = Convert.ToInt32(Application["value"]) + 1;
Label1.Text = Application["value"].ToString();
}
protected void Button2_Click(object sender, EventArgs e)
{
Application["value"] = Convert.ToInt32(Application["value"]) - 1;
Label1.Text = Application["value"].ToString();
}
protected void Button3_Click(object sender, EventArgs e)
{
Response.Redirect("Default2.aspx");
}
}
Note: application state test program ကို စမ္းဖို႔အတြက္ browser ၂ခု ၃ခု ဖြင့္ျပီး စမ္းၾကည့္လို႔ရပါတယ္။


