บทนำ
ในสภาพแวดล้อมไร้สัญชาติเช่นเว็บแอปพลิเคชัน การทำความเข้าใจแนวคิดของสถานะเซสชันไม่มีความหมายที่แท้จริง อย่างไรก็ตาม การจัดการสถานะที่มีประสิทธิภาพเป็นคุณสมบัติที่ต้องมีสำหรับเว็บแอปพลิเคชันส่วนใหญ่ Microsoft ASP.NET เช่นเดียวกับสภาพแวดล้อมการเขียนโปรแกรมฝั่งเซิร์ฟเวอร์อื่นๆ จัดให้มีเลเยอร์นามธรรมที่อนุญาตให้แอปพลิเคชันจัดเก็บข้อมูลถาวรตามผู้ใช้และต่อแอปพลิเคชัน
สิ่งสำคัญคือต้องทราบว่าสถานะเซสชันของแอปพลิเคชันเว็บคือข้อมูลที่แอปพลิเคชันแคชและดึงข้อมูลผ่านคำขอต่างๆ เซสชันแสดงถึงคำขอทั้งหมดที่ผู้ใช้ส่งในขณะที่เชื่อมต่อกับไซต์ และสถานะเซสชันคือการรวบรวมข้อมูลถาวรที่สร้างและใช้โดยผู้ใช้ในระหว่างเซสชัน สถานะของแต่ละเซสชันเป็นอิสระจากกันและสิ้นสุดเมื่อเซสชันผู้ใช้สิ้นสุดลง
สถานะเซสชันไม่มีการโต้ตอบกับเอนทิตีลอจิคัลใดๆ ที่ประกอบเป็นโปรโตคอล HTTP และข้อกำหนด เซสชันเป็นเลเยอร์นามธรรมที่สร้างขึ้นโดยสภาพแวดล้อมการพัฒนาฝั่งเซิร์ฟเวอร์ เช่น ASP และ ASP.NET แบบดั้งเดิม วิธีที่ ASP.NET แสดงสถานะเซสชันและวิธีการใช้งานสถานะเซสชันภายในนั้นขึ้นอยู่กับโครงสร้างพื้นฐานของแพลตฟอร์ม ดังนั้น ASP แบบดั้งเดิมและ ASP.NET จึงใช้สถานะเซสชันในลักษณะที่แตกต่างกันโดยสิ้นเชิง และคาดว่าจะมีการปรับปรุงและปรับปรุงเพิ่มเติมใน ASP.NET เวอร์ชันถัดไป
บทความนี้อธิบายวิธีการใช้สถานะเซสชันใน ASP.NET 1.1 และวิธีการเพิ่มประสิทธิภาพการจัดการสถานะเซสชันในแอปพลิเคชันเว็บที่มีการจัดการ
ภาพรวมสถานะเซสชัน ASP.NET
สถานะเซสชันไม่ได้เป็นส่วนหนึ่งของโครงสร้างพื้นฐาน HTTP นั่นคือควรมีองค์ประกอบโครงสร้างที่เชื่อมโยงสถานะเซสชันกับคำขอที่เข้ามาแต่ละรายการ สภาพแวดล้อมรันไทม์ (ASP ดั้งเดิมหรือ ASP.NET) สามารถรับคำสำคัญเช่นเซสชันและใช้เพื่อระบุบล็อกข้อมูลที่จัดเก็บไว้ในเซิร์ฟเวอร์ เพื่อแก้ไขปัญหาการเรียกอ็อบเจ็กต์เซสชันได้สำเร็จ สภาพแวดล้อมรันไทม์จะต้องเพิ่มสถานะเซสชันให้กับบริบทการโทรของคำขอที่กำลังประมวลผล วิธีการดำเนินการจะแตกต่างกันไปในแต่ละแพลตฟอร์ม แต่เป็นพื้นฐานของแอปพลิเคชันเว็บแบบมีสถานะ
ใน ASP ดั้งเดิม สถานะเซสชันจะถูกนำไปใช้เป็นวัตถุ COM แบบเธรดอิสระที่มีอยู่ในไลบรารี asp.dll (คุณสงสัยหรือไม่ CLSID ของออบเจ็กต์นี้คือ D97A6DA0-A865-11cf-83AF-00A0C90C2BD8 จริงๆ) ออบเจ็กต์นี้จัดเก็บข้อมูลที่จัดเป็นชุดของคู่ชื่อ/ค่า ตัวยึดตำแหน่ง "ชื่อ" แสดงถึงคีย์ที่ใช้ในการดึงข้อมูล ในขณะที่ตัวยึดตำแหน่ง "ค่า" แสดงถึงสิ่งที่เก็บไว้ในสถานะเซสชัน คู่ชื่อ/ค่าจะถูกจัดกลุ่มตามรหัสเซสชัน เพื่อให้ผู้ใช้แต่ละคนเห็นเฉพาะคู่ชื่อ/ค่าที่เขาหรือเธอสร้างขึ้น
ใน ASP.NET อินเทอร์เฟซการเขียนโปรแกรมสำหรับสถานะเซสชันเกือบจะเหมือนกับใน ASP ดั้งเดิม แต่การใช้งานขั้นพื้นฐานนั้นแตกต่างอย่างสิ้นเชิง ก่อนที่เราจะเจาะลึกสถานะเซสชันของ ASP.NET เรามาทบทวนความสามารถเชิงโครงสร้างของโครงสร้างพื้นฐานเซสชัน ASP.NET กันก่อน
ใน ASP.NET คำขอ HTTP ขาเข้าใดๆ จะถูกส่งผ่านโมดูล HTTP แต่ละโมดูลสามารถกรองและแก้ไขข้อมูลจำนวนมากตามคำขอได้ ข้อมูลที่เกี่ยวข้องกับแต่ละคำขอเรียกว่า "บริบทการโทร" ซึ่งแสดงโดยวัตถุ HttpContext ในการเขียนโปรแกรม เราไม่ควรคิดว่าบริบทคำขอเป็นอีกที่เก็บข้อมูลสถานะ แม้ว่าคอลเลกชันรายการที่มีให้นั้นเป็นเพียงที่เก็บข้อมูลก็ตาม ออบเจ็กต์ HttpContext แตกต่างจากออบเจ็กต์สถานะอื่นๆ ทั้งหมด (เช่น เซสชัน แอปพลิเคชัน และแคช) โดยมีอายุการใช้งานที่จำกัดเกินกว่าเวลาที่จำเป็นในการจัดการคำขอ เมื่อคำขอส่งผ่านชุดของโมดูล HTTP ที่ลงทะเบียนไว้ วัตถุ HttpContext จะมีการอ้างอิงไปยังวัตถุสถานะ เมื่อสามารถประมวลผลคำขอได้ในที่สุด บริบทการโทรที่เกี่ยวข้องจะถูกผูกไว้กับเซสชันเฉพาะ (เซสชัน) และออบเจ็กต์สถานะโกลบอล (แอปพลิเคชันและแคช)
โมดูล HTTP ที่รับผิดชอบในการตั้งค่าสถานะเซสชันของผู้ใช้แต่ละรายคือ SessionStateModule โครงสร้างของโมดูลนี้ได้รับการออกแบบตามอินเทอร์เฟซ IHttpModule ซึ่งให้บริการที่เกี่ยวข้องกับสถานะเซสชันจำนวนมากสำหรับแอปพลิเคชัน ASP.NET รวมถึงการสร้างรหัสเซสชัน การจัดการเซสชันที่ไม่มีคุกกี้ การดึงข้อมูลเซสชันจากผู้ให้บริการสถานะภายนอก และการเชื่อมโยงข้อมูลกับบริบทการโทรของคำขอ
โมดูล HTTP ไม่ได้เก็บข้อมูลเซสชันไว้ภายใน สถานะเซสชันจะถูกบันทึกในองค์ประกอบภายนอกที่เรียกว่า "ผู้ให้บริการสถานะ" เสมอ ผู้ให้บริการสถานะสรุปข้อมูลสถานะเซสชันอย่างสมบูรณ์และสื่อสารกับส่วนอื่นๆ ผ่านวิธีการของอินเทอร์เฟซ IStateClientManager วิธีการเรียกโมดูล HTTP สถานะเซสชันบนอินเทอร์เฟซนี้เพื่ออ่านและบันทึกสถานะเซสชัน ASP.NET 1.1 รองรับผู้ให้บริการสถานะที่แตกต่างกันสามราย ดังแสดงในตารางที่ 1
ตารางที่ 1: สถานะ ผู้ให้บริการไคลเอ็นต์
ผู้ให้บริการ คำอธิบาย
ค่าเซสชัน InProc ยังคงเป็นวัตถุที่ใช้งานอยู่ในหน่วยความจำของกระบวนการของผู้ปฏิบัติงาน ASP.NET (aspnet_wp.exe หรือ w3wp.exe ใน Microsoft® Windows Server® 2003) นี่คือตัวเลือกเริ่มต้น
ค่าเซสชัน StateServer จะถูกทำให้เป็นอนุกรมและจัดเก็บไว้ในหน่วยความจำในกระบวนการแยกต่างหาก (aspnet_state.exe) กระบวนการนี้สามารถทำงานบนคอมพิวเตอร์เครื่องอื่นได้
ค่าเซสชัน SQLServer จะถูกทำให้เป็นอนุกรมและจัดเก็บไว้ในตาราง Microsoft® SQL Server® อินสแตนซ์ของ SQL Server สามารถทำงานได้ภายในเครื่องหรือจากระยะไกล
โมดูล HTTP สถานะเซสชันอ่านผู้ให้บริการสถานะที่เลือกในปัจจุบันจากส่วน <sessionState> ของไฟล์ web.config
<sessionState mode="InProc | StateServer | SQLServer />;
ขึ้นอยู่กับค่าของแอตทริบิวต์โหมด สถานะของเซสชันจะถูกดึงมาจากและเก็บไว้ในกระบวนการที่แตกต่างกันผ่านขั้นตอนที่แตกต่างกัน โดยค่าเริ่มต้น สถานะของเซสชันจะถูกเก็บไว้ในในเครื่อง กระบวนการของผู้ปฏิบัติงาน ASP.NET ในกรณีพิเศษ จะถูกจัดเก็บไว้ในสล็อตเฉพาะของวัตถุแคช ASP.NET (ไม่สามารถเข้าถึงได้โดยทางโปรแกรม) สถานะเซสชันสามารถจัดเก็บภายนอกได้แม้ในกระบวนการระยะไกล ( ตัวอย่างเช่น ใน Windows บริการ NT ชื่อ aspnet_state.exe) ตัวเลือกที่สามคือการจัดเก็บสถานะเซสชันในตารางฐานข้อมูลเฉพาะที่จัดการโดย SQL Server 2000
โมดูล HTTP จะทำการดีซีเรียลไลซ์ค่าเซสชันที่จุดเริ่มต้นของคำขอ ทำให้เป็นพจนานุกรม (จริงๆ แล้ว วัตถุประเภท HttpSessionState) จะถูกเข้าถึงโดยทางโปรแกรมผ่านคุณสมบัติเซสชันที่เปิดเผยโดยคลาส (เช่น HttpContext และ Page) การเชื่อมโยงจะคงอยู่จนกว่าคำขอจะสิ้นสุดลง หากคำขอเสร็จสมบูรณ์ ค่าสถานะทั้งหมดจะถูกทำให้เป็นอนุกรมกลับ ไปยังผู้ให้บริการสถานะและพร้อมใช้งานสำหรับการร้องขออื่น ๆ
รูปที่ 1 แสดงการสื่อสารระหว่างเพจ ASP.NET ที่ร้องขอและค่าเซสชัน โค้ดที่ใช้โดยแต่ละเพจเกี่ยวข้องกับแอตทริบิวต์เซสชันในคลาสเพจ เช่นเดียวกับ ASP แบบดั้งเดิม
รูปที่ 1: สถาปัตยกรรมสถานะเซสชันใน ASP.NET 1.1
ค่าทางกายภาพของสถานะเซสชันถูกล็อคตามเวลาที่ต้องดำเนินการตามคำขอ การล็อคนี้ได้รับการจัดการภายในโดยโมดูล HTTP และใช้เพื่อซิงโครไนซ์การเข้าถึงสถานะเซสชัน
โมดูลสถานะเซสชันจะสร้างอินสแตนซ์ของผู้ให้บริการสถานะของแอปพลิเคชันและเริ่มต้นด้วยข้อมูลที่อ่านจากไฟล์ web.config ถัดไป ผู้ให้บริการแต่ละรายจะดำเนินการเริ่มต้นของตนเองต่อไป การดำเนินการเริ่มต้นจะแตกต่างกันไปมากขึ้นอยู่กับประเภทของผู้ให้บริการ ตัวอย่างเช่น ตัวจัดการสถานะของ SQL Server จะเปิดการเชื่อมต่อกับฐานข้อมูลที่กำหนด ในขณะที่ตัวจัดการที่ไม่อยู่ในกระบวนการจะตรวจสอบพอร์ต TCP ที่ระบุ ในทางกลับกัน ผู้จัดการสถานะ InProc จะเก็บข้อมูลอ้างอิงไปยังฟังก์ชันการโทรกลับ การดำเนินการนี้จะดำเนินการเมื่อมีการลบองค์ประกอบออกจากแคช และใช้เพื่อทริกเกอร์เหตุการณ์ Session_OnEnd ของแอปพลิเคชัน
การเข้าถึงสถานะเซสชันแบบซิงโครนัส
จะเกิดอะไรขึ้นเมื่อเว็บเพจทำการเรียกคุณสมบัติเซสชันอย่างง่ายดายและใช้งานง่าย การดำเนินการหลายอย่างดำเนินการในเบื้องหลัง ดังที่แสดงในโค้ดที่ยุ่งยากต่อไปนี้:
int siteCount = Convert.ToInt32(Session["Counter"]);
โค้ดข้างต้นเข้าถึงค่าเซสชันที่สร้างขึ้นโดยโมดูล HTTP ในหน่วยความจำภายในเครื่อง อ่านข้อมูลจากผู้ให้บริการของรัฐเฉพาะ (ดูรูปที่ 1) จะเกิดอะไรขึ้นหากเพจอื่นพยายามเข้าถึงสถานะเซสชันพร้อมกัน ในกรณีนี้ คำขอปัจจุบันอาจหยุดการประมวลผลข้อมูลที่ไม่สอดคล้องกันหรือข้อมูลเก่า เพื่อหลีกเลี่ยงปัญหานี้ โมดูลสถานะเซสชันจะใช้กลไกการล็อกตัวอ่าน/ตัวเขียนและคิวการเข้าถึงค่าสถานะ เพจที่มีสิทธิ์เขียนในสถานะเซสชันจะยังคงล็อกตัวเขียนสำหรับเซสชันนั้นจนกว่าคำขอจะสิ้นสุดลง
เพจสามารถขอสิทธิ์ในการเขียนสำหรับสถานะเซสชันได้โดยการตั้งค่าคุณสมบัติ EnableSessionState ของคำสั่ง @Page เป็นจริง (นี่คือการตั้งค่าเริ่มต้น) อย่างไรก็ตาม เพจยังสามารถเข้าถึงสถานะเซสชันแบบอ่านอย่างเดียวได้ เช่น เมื่อคุณสมบัติ EnableSessionState ถูกตั้งค่าเป็น ReadOnly ในกรณีนี้ โมดูลจะคงการล็อกผู้อ่านไว้สำหรับเซสชันนั้นจนกว่าคำขอสำหรับเพจนั้นจะสิ้นสุดลง ผลที่ได้คือการอ่านพร้อมกันจะเกิดขึ้น
หากคำขอเพจตั้งค่าการล็อกผู้อ่าน คำขออื่นๆ ที่เกิดขึ้นพร้อมกันในเซสชันเดียวกันจะไม่สามารถอัปเดตสถานะเซสชันได้ แต่อย่างน้อยก็จะสามารถอ่านได้ นั่นคือ หากคำขอแบบอ่านอย่างเดียวกำลังถูกประมวลผลสำหรับเซสชัน คำขอแบบอ่านอย่างเดียวที่รอดำเนินการจะมีลำดับความสำคัญสูงกว่าคำขอที่ต้องการการเข้าถึงแบบเต็ม หากคำขอเพจตั้งค่าการล็อกตัวเขียนสำหรับสถานะเซสชัน หน้าอื่นๆ ทั้งหมดจะถูกบล็อกไม่ว่าพวกเขาต้องการอ่านหรือเขียนเนื้อหาก็ตาม ตัวอย่างเช่น หากสองเฟรมพยายามเขียนลงในเซสชันพร้อมกัน หนึ่งเฟรมต้องรอจนกว่าอีกเฟรมหนึ่งจะเสร็จสิ้นก่อนจึงจะสามารถเขียนได้
การเปรียบเทียบผู้ให้บริการสถานะ
ตามค่าเริ่มต้น แอปพลิเคชัน ASP.NET จะเก็บสถานะเซสชันไว้ในหน่วยความจำของกระบวนการของผู้ปฏิบัติงาน โดยเฉพาะในช่องเฉพาะของวัตถุแคช เมื่อเลือกโหมด InProc สถานะเซสชันจะถูกจัดเก็บไว้ในช่องภายในออบเจ็กต์แคช ช่องนี้ถูกทำเครื่องหมายว่าเป็นช่องส่วนตัวและไม่สามารถเข้าถึงได้โดยทางโปรแกรม กล่าวอีกนัยหนึ่ง ถ้าคุณระบุรายการทั้งหมดในแคชข้อมูล ASP.NET จะไม่มีส่งคืนวัตถุที่คล้ายกับสถานะเซสชันที่กำหนด ออบเจ็กต์แคชมีสล็อตสองประเภท: สล็อตส่วนตัวและสล็อตสาธารณะ โปรแกรมเมอร์สามารถเพิ่มและจัดการสล็อตสาธารณะได้ แต่สล็อตส่วนตัวสามารถใช้ได้โดยระบบเท่านั้น (โดยเฉพาะคลาสที่กำหนดใน system.web part)
สถานะของแต่ละเซสชันที่ใช้งานอยู่จะใช้ช่องเฉพาะในแคช ช่องนี้ตั้งชื่อตามรหัสเซสชัน และค่าของช่องนั้นเป็นอินสแตนซ์ของคลาสที่ไม่ได้ประกาศภายในชื่อ SessionStateItem ผู้ให้บริการสถานะ InProc ได้รับรหัสเซสชันและดึงข้อมูลองค์ประกอบที่เกี่ยวข้องในแคช เนื้อหาของออบเจ็กต์ SessionStateItem จะถูกป้อนลงในออบเจ็กต์พจนานุกรม HttpSessionState และเข้าถึงได้โดยแอปพลิเคชันผ่านคุณสมบัติเซสชัน โปรดทราบว่ามีจุดบกพร่องใน ASP.NET 1.0 ที่ทำให้สล็อตส่วนตัวของวัตถุแคชสามารถนับได้โดยทางโปรแกรม หากคุณเรียกใช้โค้ดต่อไปนี้ภายใต้ ASP.NET 1.0 คุณจะสามารถระบุรายการที่สอดคล้องกับออบเจ็กต์ที่มีอยู่ในแต่ละสถานะเซสชันที่ใช้งานอยู่ในปัจจุบันได้
foreach (องค์ประกอบพจนานุกรมในแคช)
-
Response.Write(elem.Key + ": " + elem.Value.ToString());
}
ข้อผิดพลาดนี้ได้รับการแก้ไขแล้วใน ASP.NET 1.1 และเมื่อคุณระบุเนื้อหาที่แคชไว้ จะไม่มีการระบุสล็อตระบบอีกต่อไป
InProc น่าจะเป็นตัวเลือกการเข้าถึงที่เร็วที่สุดในตอนนี้ แต่โปรดจำไว้ว่ายิ่งมีข้อมูลเก็บไว้ในเซสชันมากเท่าใด เว็บเซิร์ฟเวอร์ก็จะยิ่งใช้หน่วยความจำมากขึ้นเท่านั้น ซึ่งอาจเพิ่มความเสี่ยงที่ประสิทธิภาพจะลดลง หากคุณวางแผนที่จะใช้โซลูชันที่ไม่อยู่ในกระบวนการใดๆ คุณควรพิจารณาอย่างรอบคอบถึงผลกระทบที่เป็นไปได้ของการทำให้เป็นอนุกรมและการดีซีเรียลไลซ์ โซลูชันที่ไม่อยู่ในกระบวนการใช้บริการ Windows NT (aspnet_state.exe) หรือตาราง SQL Server เพื่อจัดเก็บค่าเซสชัน ดังนั้น สถานะเซสชันยังคงอยู่นอกกระบวนการของผู้ปฏิบัติงาน ASP.NET และเลเยอร์ของโค้ดเพิ่มเติมจำเป็นต้องทำให้เป็นซีเรียลไลซ์และดีซีเรียลไลซ์ระหว่างสถานะเซสชันและสื่อเก็บข้อมูลจริง สิ่งนี้จะเกิดขึ้นทุกครั้งที่มีการประมวลผลคำขอ และจะต้องได้รับการปรับให้เหมาะสมในระดับสูงสุด
เนื่องจากจำเป็นต้องคัดลอกข้อมูลเซสชันจากพื้นที่เก็บข้อมูลภายนอกไปยังพจนานุกรมเซสชันในเครื่อง คำขอส่งผลให้ประสิทธิภาพลดลงตั้งแต่ 15% (ไม่อยู่ในกระบวนการ) ถึง 25% (SQL Server) โปรดทราบว่าแม้จะเป็นเพียงการประมาณการคร่าวๆ แต่ควรใกล้เคียงกับผลกระทบขั้นต่ำ และผลกระทบสูงสุดจะสูงกว่านี้มาก ที่จริงแล้ว การประมาณนี้ไม่ได้คำนึงถึงความซับซ้อนของประเภทที่บันทึกไว้ในสถานะเซสชันโดยสมบูรณ์
ในสถานการณ์การจัดเก็บข้อมูลนอกกระบวนการ สถานะเซสชันจะอยู่ได้นานขึ้น ทำให้แอปพลิเคชันมีประสิทธิภาพมากขึ้น เนื่องจากป้องกัน Microsoft® Internet Information Services (IIS) และความล้มเหลวของ ASP.NET ด้วยการแยกสถานะเซสชันออกจากแอปพลิเคชัน คุณสามารถขยายแอปพลิเคชันที่มีอยู่ไปยังสถาปัตยกรรม Web Farm และ Web Garden ได้ง่ายขึ้น นอกจากนี้ สถานะเซสชันจะถูกจัดเก็บไว้ในกระบวนการภายนอก ซึ่งช่วยลดความเสี่ยงที่ข้อมูลจะสูญหายเป็นระยะเนื่องจากการวนซ้ำของกระบวนการ
ต่อไปนี้เป็นวิธีใช้บริการ Windows NT ตามที่กล่าวไว้ข้างต้น บริการ NT เป็นกระบวนการชื่อ aspnet_state.exe ซึ่งโดยปกติจะอยู่ในโฟลเดอร์ C:WINNTMicrosoft.NETFrameworkv1.1.4322
ไดเร็กทอรีที่แท้จริงขึ้นอยู่กับเวอร์ชันของ Microsoft® .NET Framework ที่คุณใช้งานอยู่ ก่อนที่จะใช้เซิร์ฟเวอร์สถานะ คุณควรตรวจสอบให้แน่ใจว่าบริการพร้อมใช้งานและทำงานบนคอมพิวเตอร์ภายในเครื่องหรือระยะไกลที่ใช้เป็นอุปกรณ์จัดเก็บข้อมูลเซสชัน บริการสถานะเป็นส่วนหนึ่งของและติดตั้งด้วย ASP.NET ดังนั้นคุณไม่จำเป็นต้องเรียกใช้โปรแกรมติดตั้งเพิ่มเติม ตามค่าเริ่มต้น บริการสถานะจะไม่ทำงานและจำเป็นต้องเริ่มต้นด้วยตนเอง แอปพลิเคชัน ASP.NET จะพยายามสร้างการเชื่อมต่อกับเซิร์ฟเวอร์สถานะทันทีหลังจากโหลด ดังนั้น บริการจะต้องพร้อมใช้งาน มิฉะนั้น ข้อยกเว้น HTTP จะถูกส่งออกไป รูปภาพต่อไปนี้แสดงกล่องโต้ตอบคุณสมบัติของบริการ
รูปที่ 2: กล่องโต้ตอบคุณสมบัติเซิร์ฟเวอร์สถานะ ASP.NET
แอปพลิเคชัน ASP.NET จำเป็นต้องระบุที่อยู่ TCP/IP ของคอมพิวเตอร์ที่มีบริการสถานะเซสชันอยู่ ต้องป้อนการตั้งค่าต่อไปนี้ลงในไฟล์ web.config ของแอปพลิเคชัน
<การกำหนดค่า>;
<system.เว็บ>;
<สถานะเซสชัน
โหมด = "เซิร์ฟเวอร์สถานะ"
stateConnectionString="tcpip=expoware:42424" />;
</system.web><;
</configuration>;
คุณลักษณะ stateConnectionString ประกอบด้วยที่อยู่ IP ของคอมพิวเตอร์และพอร์ตที่ใช้สำหรับการแลกเปลี่ยนข้อมูล ที่อยู่คอมพิวเตอร์เริ่มต้นคือ 127.0.0.1 (localhost) และพอร์ตเริ่มต้นคือ 42424 คุณยังสามารถระบุชื่อคอมพิวเตอร์ได้ด้วย การใช้คอมพิวเตอร์ในพื้นที่หรือระยะไกลจะทำให้โค้ดโปร่งใสโดยสมบูรณ์ โปรดทราบว่าไม่สามารถใช้อักขระที่ไม่ใช่ ASCII ในชื่อได้ และจำเป็นต้องระบุหมายเลขพอร์ต
ถ้าคุณใช้ที่เก็บข้อมูลเซสชันที่ไม่อยู่ในกระบวนการ สถานะเซสชันจะยังคงมีอยู่และพร้อมใช้งานในอนาคตโดยไม่คำนึงถึงสิ่งที่เกิดขึ้นกับกระบวนการของผู้ปฏิบัติงาน ASP.NET หากบริการถูกขัดจังหวะ ข้อมูลจะถูกเก็บไว้และดึงข้อมูลโดยอัตโนมัติเมื่อบริการถูกกู้คืน อย่างไรก็ตาม หากบริการของผู้ให้บริการสถานะหยุดหรือล้มเหลว ข้อมูลจะสูญหาย หากคุณต้องการให้แอปพลิเคชันของคุณมีประสิทธิภาพ ให้ใช้โหมด SQLServer แทนโหมด StateServer
<การกำหนดค่า>;
<system.เว็บ>;
<สถานะเซสชัน
โหมด = "SQLServer"
sqlConnectionString="server=127.0.0.1;uid=<user id><;;pwd=<password><;;" />;
</system.web><;
</configuration>;
คุณสามารถระบุสตริงการเชื่อมต่อผ่านแอตทริบิวต์ sqlConnectionString โปรดทราบว่าสตริงแอ็ตทริบิวต์ต้องมี ID ผู้ใช้ รหัสผ่าน และชื่อเซิร์ฟเวอร์ ไม่สามารถมีแท็ก เช่น ฐานข้อมูล และแค็ตตาล็อกเริ่มต้นได้ เนื่องจากข้อมูลนี้มีค่าเริ่มต้นเป็นชื่อคงที่ ID ผู้ใช้และรหัสผ่านสามารถแทนที่ได้ด้วยการตั้งค่าความปลอดภัยแบบรวม
จะสร้างฐานข้อมูลได้อย่างไร? ASP.NET มีสคริปต์สองคู่เพื่อกำหนดค่าสภาพแวดล้อมฐานข้อมูล สคริปต์คู่แรกมีชื่อว่า InstallSqlState.sql และ UninstallSqlState.sql และอยู่ในโฟลเดอร์เดียวกันกับบริการ Session State NT พวกเขาสร้างฐานข้อมูลชื่อ ASPState และขั้นตอนการจัดเก็บต่างๆ อย่างไรก็ตาม ข้อมูลจะถูกจัดเก็บไว้ในฐานข้อมูล TempDB พื้นที่เก็บข้อมูลชั่วคราวของ SQL Server ซึ่งหมายความว่า ถ้าคอมพิวเตอร์ SQL Server ถูกรีสตาร์ท ข้อมูลเซสชันจะสูญหาย
เมื่อต้องการแก้ไขข้อจำกัดนี้ ให้ใช้สคริปต์คู่ที่สอง สคริปต์คู่ที่สองชื่อ InstallPersistSqlState.sql และ UninstallPersistSqlState.sql ในกรณีนี้ ฐานข้อมูล ASPState จะถูกสร้างขึ้น แต่ตารางจะถูกสร้างขึ้นในฐานข้อมูลเดียวกันและยังคงอยู่เช่นกัน เมื่อคุณติดตั้งการสนับสนุน SQL Server สำหรับเซสชัน งานจะถูกสร้างขึ้นเพื่อลบเซสชันที่หมดอายุในฐานข้อมูลสถานะเซสชันด้วย งานชื่อ ASPState_Job_DeleteExpiredSessions และทำงานอยู่เสมอ โปรดทราบว่าเพื่อให้งานนี้ทำงานได้อย่างถูกต้อง บริการ SQLServerAgent จำเป็นต้องทำงานอยู่
ไม่ว่าคุณจะเลือกโหมดใด วิธีการเข้ารหัสการดำเนินการสถานะเซสชันจะไม่เปลี่ยนแปลง คุณสามารถทำงานกับคุณสมบัติ Session และอ่านและเขียนค่าได้ตามปกติ ความแตกต่างในพฤติกรรมทั้งหมดได้รับการจัดการในระดับนามธรรมที่ต่ำกว่า การทำให้เป็นอนุกรมของรัฐอาจเป็นความแตกต่างที่สำคัญที่สุดระหว่างโหมดเซสชัน
สถานะการทำให้เป็นอนุกรมและดีซีเรียลไลซ์
เมื่อใช้โหมดในกระบวนการ ออบเจ็กต์จะถูกจัดเก็บไว้ในสถานะเซสชันเป็นอินสแตนซ์ที่ใช้งานอยู่ของคลาสที่เกี่ยวข้อง ถ้าไม่มีการซีเรียลไลซ์และการดีซีเรียลไลซ์จริงเกิดขึ้น หมายความว่าคุณสามารถจัดเก็บออบเจ็กต์ใดๆ ที่คุณสร้างในเซสชันได้ (รวมถึงออบเจ็กต์ที่ไม่สามารถซีเรียลไลซ์และออบเจ็กต์ COM) ได้ และการเข้าถึงวัตถุเหล่านั้นจะไม่แพงเกินไป หากคุณเลือกผู้ให้บริการของรัฐที่ไม่อยู่ในกระบวนการ ก็อีกเรื่องหนึ่ง
ในสถาปัตยกรรมที่ไม่อยู่ในกระบวนการ ค่าเซสชันจะถูกคัดลอกจากสื่อเก็บข้อมูลในเครื่อง (ฐานข้อมูล AppDomain ภายนอก) ไปยังหน่วยความจำของ AppDomain ที่จัดการคำขอ จำเป็นต้องมีเลเยอร์ซีเรียลไลซ์เซชัน/ดีซีเรียลไลเซชันเพื่อทำงานนี้ให้สำเร็จ และถือเป็นต้นทุนหลักประการหนึ่งของผู้ให้บริการของรัฐที่ไม่อยู่ในกระบวนการ ผลกระทบหลักที่สถานการณ์นี้มีต่อโค้ดของคุณคือ เฉพาะออบเจ็กต์ที่ทำให้เป็นอนุกรมเท่านั้นที่สามารถจัดเก็บไว้ในพจนานุกรมเซสชันได้
ASP.NET ใช้สองวิธีในการซีเรียลไลซ์และดีซีเรียลไลซ์ข้อมูล ขึ้นอยู่กับประเภทของข้อมูลที่เกี่ยวข้อง สำหรับประเภทพื้นฐาน ASP.NET จะใช้ตัวจัดลำดับภายในที่ปรับให้เหมาะสม สำหรับประเภทอื่น รวมถึงอ็อบเจ็กต์และคลาสที่ผู้ใช้กำหนด ASP.NET จะใช้ตัวจัดรูปแบบไบนารี .NET ประเภทพื้นฐานประกอบด้วยสตริง วันที่เวลา ค่าบูลีน ไบต์ อักขระ และประเภทตัวเลขทั้งหมด สำหรับประเภทเหล่านี้ การใช้ซีเรียลไลเซอร์ที่ออกแบบโดยเฉพาะจะเร็วกว่าการใช้ฟอร์แมตเตอร์ไบนารี .NET ทั่วไปที่เป็นค่าเริ่มต้น
ซีเรียลไลเซอร์ที่ปรับให้เหมาะสมไม่ได้เผยแพร่หรือจัดทำเป็นเอกสารต่อสาธารณะ มันเป็นเพียงเครื่องอ่าน/เขียนไบนารี่และใช้สถาปัตยกรรมการจัดเก็บข้อมูลที่เรียบง่ายแต่มีประสิทธิภาพ ซีเรียลไลเซอร์ใช้คลาส BinaryWriter เพื่อเขียนการแสดงไบต์ของชนิด จากนั้นเขียนการแสดงไบต์ของค่าที่สอดคล้องกับชนิดนั้น เมื่ออ่านไบต์แบบอนุกรม คลาสจะแยกไบต์ก่อน ตรวจพบชนิดข้อมูลที่จะอ่าน จากนั้นเรียกเมธอด ReadXxx เฉพาะชนิดบนคลาส BinaryReader
โปรดทราบว่าขนาดของประเภทบูลีนและตัวเลขเป็นที่ทราบกันดี แต่ไม่ใช่สำหรับสตริง ในสตรีมข้อมูลพื้นฐาน สตริงจะขึ้นหน้าด้วยความยาวคงที่เสมอ (โค้ดจำนวนเต็ม 7 บิตเขียนในแต่ละครั้ง) และผู้อ่านจะใช้ข้อเท็จจริงนี้เพื่อกำหนดขนาดที่ถูกต้องของสตริง ค่าวันที่จะถูกบันทึกโดยการเขียนเฉพาะจำนวนโทเค็นทั้งหมดที่ประกอบเป็นวันที่ ดังนั้น เมื่อต้องการทำให้เซสชันเป็นอนุกรม วันที่ควรเป็นประเภท Int64
คุณสามารถใช้คลาส BinaryFormatter เพื่อดำเนินการซีเรียลไลซ์บนออบเจ็กต์ที่ซับซ้อนมากขึ้น (รวมถึงออบเจ็กต์แบบกำหนดเอง) ได้ตราบใดที่คลาสที่บรรจุถูกทำเครื่องหมายว่าเป็นซีเรียลไลซ์ได้ ประเภทที่ไม่ใช่ประเภทพื้นฐานทั้งหมดจะถูกระบุด้วยรหัสประเภทเดียวกัน และจัดเก็บไว้ในสตรีมข้อมูลเดียวกันกับประเภทพื้นฐาน โดยรวมแล้ว การดำเนินการซีเรียลไลซ์อาจส่งผลให้ประสิทธิภาพลดลง 15% ถึง 25% อย่างไรก็ตาม โปรดทราบว่านี่เป็นการประมาณการคร่าวๆ โดยอิงตามสมมติฐานที่ใช้ประเภทพื้นฐาน ยิ่งประเภทที่ใช้ซับซ้อนมากเท่าใด ค่าใช้จ่ายก็จะมากขึ้นตามไปด้วย
การจัดเก็บข้อมูลเซสชั่นที่มีประสิทธิภาพเป็นเรื่องยากที่จะนำไปใช้โดยไม่ต้องใช้ประเภทดั้งเดิมอย่างกว้างขวาง ดังนั้น อย่างน้อยในทางทฤษฎี การใช้ช่องเซสชันสามช่องเพื่อบันทึกคุณสมบัติสตริงที่แตกต่างกันสามประการของอ็อบเจ็กต์นั้นดีกว่าการทำให้อ็อบเจ็กต์เป็นอนุกรมทั้งหมด แต่จะเกิดอะไรขึ้นถ้าวัตถุที่คุณต้องการทำให้เป็นอนุกรมมีคุณสมบัติ 100 รายการ? คุณต้องการใช้ 100 ช่องหรือเพียงช่องเดียว? ในหลายกรณี วิธีที่ดีกว่าคือการแปลงประเภทที่ซับซ้อนให้เป็นประเภทที่ง่ายกว่าหลายประเภท วิธีการนี้ขึ้นอยู่กับตัวแปลงประเภท "ตัวแปลงประเภท" คือซีเรียลไลเซอร์น้ำหนักเบาที่ส่งคืนคุณสมบัติหลักของประเภทเป็นชุดของสตริง ตัวแปลงประเภทเป็นคลาสภายนอกที่ถูกผูกไว้กับคลาสฐานโดยใช้แอ็ตทริบิวต์ ขึ้นอยู่กับผู้เขียนประเภทที่จะตัดสินใจว่าคุณสมบัติใดจะถูกบันทึกและอย่างไร ตัวแปลงประเภทยังมีประโยชน์สำหรับพื้นที่จัดเก็บ ViewState และแสดงถึงวิธีการจัดเก็บเซสชันที่มีประสิทธิภาพมากกว่าตัวจัดรูปแบบไบนารี
วงจรชีวิตของเซสชัน
จุดสำคัญเกี่ยวกับการจัดการเซสชันของ ASP.NET คือ วงจรชีวิตของวัตถุสถานะเซสชันเริ่มต้นเมื่อมีการเพิ่มรายการแรกลงในพจนานุกรมในหน่วยความจำเท่านั้น เซสชัน ASP.NET จะถือว่าเริ่มต้นหลังจากดำเนินการโค้ดต่อไปนี้แล้วเท่านั้น
Session["MySlot"] = "ข้อมูลบางส่วน";
พจนานุกรม Session มักจะมีประเภท Object อยู่ หากต้องการอ่านข้อมูลย้อนหลัง ค่าที่ส่งคืนจะต้องถูกแปลงเป็นประเภทที่เฉพาะเจาะจงมากขึ้น
string data = (string) Session["MySlot"];
เมื่อเพจบันทึกข้อมูลลงในเซสชัน ค่าจะถูกโหลดลงในคลาสพจนานุกรมที่สร้างขึ้นเป็นพิเศษซึ่งมีอยู่ในคลาส HttpSessionState เนื้อหาของพจนานุกรมจะถูกโหลดลงในผู้ให้บริการของรัฐเมื่อคำขอที่ประมวลผลในปัจจุบันเสร็จสมบูรณ์ ถ้าสถานะเซสชันว่างเปล่าเนื่องจากข้อมูลไม่ได้ใส่ลงในพจนานุกรมโดยทางโปรแกรม ข้อมูลจะไม่ถูกทำให้เป็นอนุกรมกับสื่อจัดเก็บข้อมูล และที่สำคัญกว่านั้น จะไม่ให้บริการใน ASP.NET Cache, SQL Server หรือ NT State Services Create ช่องเพื่อติดตามเซสชันปัจจุบัน นี่เป็นเหตุผลด้านประสิทธิภาพ แต่มีผลกระทบสำคัญต่อวิธีจัดการรหัสเซสชัน: รหัสเซสชันใหม่จะถูกสร้างขึ้นสำหรับแต่ละคำขอจนกว่าข้อมูลบางส่วนจะถูกเก็บไว้ในพจนานุกรมของเซสชัน
เมื่อจำเป็นต้องเชื่อมต่อสถานะเซสชันกับคำขอที่กำลังประมวลผล โมดูล HTTP จะดึงข้อมูล ID เซสชัน (หากไม่ใช่คำขอเริ่มต้น) และค้นหาในผู้ให้บริการสถานะที่กำหนดค่าไว้ หากไม่มีข้อมูลถูกส่งกลับ โมดูล HTTP จะสร้าง ID เซสชันใหม่สำหรับคำขอ สามารถทดสอบได้อย่างง่ายดายด้วยเพจต่อไปนี้:
<%@ Page Language="C#" Trace="true" %>;
</html><;
<ร่างกาย>;
<ฟอร์ม runat="เซิร์ฟเวอร์";
<asp:button runat="server" text="คลิก" />;
</แบบฟอร์ม><;
</ตัว><;
</html>;
เมื่อใดก็ตามที่คุณคลิกปุ่มและกลับสู่เพจ รหัสเซสชันใหม่จะถูกสร้างขึ้นและข้อมูลการติดตามจะถูกบันทึก
รูปที่ 3: ในแอปพลิเคชันที่ไม่ได้จัดเก็บข้อมูลไว้ในพจนานุกรมเซสชัน รหัสเซสชันใหม่จะถูกสร้างขึ้นสำหรับแต่ละคำขอ
แล้วเหตุการณ์ Session_OnStart ล่ะ? งานจะยกมาทุกคำขอด้วยมั้ย? หากแอปพลิเคชันของคุณกำหนดตัวจัดการ Session_OnStart สถานะของเซสชันจะถูกบันทึกเสมอ แม้ว่าสถานะเซสชันจะว่างเปล่าก็ตาม ดังนั้น รหัสเซสชันจะเป็นค่าคงที่เสมอสำหรับคำขอทั้งหมดหลังจากการร้องขอครั้งแรก ใช้ตัวจัดการ Session_OnStart เมื่อจำเป็นจริงๆ เท่านั้น
หากเซสชันหมดเวลาหรือละทิ้ง รหัสเซสชันจะไม่เปลี่ยนแปลงในครั้งถัดไปที่มีการเข้าถึงแอปพลิเคชันไร้สัญชาติ ได้รับการออกแบบเพื่อให้ ID เซสชันคงอยู่จนกระทั่งสิ้นสุดเซสชันเบราว์เซอร์ แม้ว่าสถานะเซสชันจะหมดอายุก็ตาม นั่นคือ รหัสเซสชันเดียวกันจะใช้แทนหลายเซสชันเสมอ ตราบใดที่อินสแตนซ์ของเบราว์เซอร์เหมือนกัน
เหตุการณ์ Session_OnEnd ถือเป็นจุดสิ้นสุดของเซสชัน และใช้เพื่อรันโค้ดการล้างข้อมูลใดๆ ที่จำเป็นในการยุติเซสชัน อย่างไรก็ตาม โปรดทราบว่าเหตุการณ์นี้ได้รับการสนับสนุนในโหมด InProc เท่านั้น นั่นคือ เฉพาะเมื่อมีการจัดเก็บข้อมูลเซสชันในกระบวนการของผู้ปฏิบัติงาน ASP.NET เท่านั้น เพื่อให้เหตุการณ์ Session_OnEnd เกิดขึ้น ต้องมีสถานะของเซสชันก่อน ซึ่งหมายความว่าข้อมูลบางอย่างจะต้องถูกเก็บไว้ในสถานะเซสชัน และต้องดำเนินการตามคำขออย่างน้อยหนึ่งรายการ
ในโหมด InProc สถานะเซสชันจะถูกเพิ่มลงในแคชเนื่องจากรายการจะได้รับนโยบายเวลาหมดอายุของตัวแปร การหมดอายุของตัวแปรหมายความว่าหากไม่มีการใช้รายการภายในระยะเวลาหนึ่ง รายการนั้นจะถูกลบ เวลาหมดอายุของคำขอใดๆ ที่ประมวลผลในช่วงเวลานี้จะถูกรีเซ็ต ช่วงเวลาของรายการสถานะเซสชันถูกตั้งค่าเป็นการหมดเวลาเซสชัน เทคนิคที่ใช้ในการรีเซ็ตเวลาหมดอายุของสถานะเซสชันนั้นง่ายและใช้งานง่ายมาก: โมดูล HTTP ของเซสชันเพียงอ่านรายการสถานะเซสชันที่จัดเก็บไว้ในแคช ASP.NET ถ้าทราบโครงสร้างภายในของวัตถุแคช ASP.NET โมดูลจะทำการคำนวณเพื่อรีเซ็ตเวลาหมดอายุของตัวแปร ดังนั้นเมื่อรายการแคชหมดอายุ เซสชันจึงหมดเวลา
รายการที่หมดอายุจะถูกลบออกจากแคชโดยอัตโนมัติ โมดูลเซสชันสถานะยังแสดงถึงฟังก์ชันการโทรกลับแบบลบซึ่งเป็นส่วนหนึ่งของนโยบายเวลาหมดอายุสำหรับโครงการนี้ แคชจะเรียกใช้ฟังก์ชันลบโดยอัตโนมัติ ซึ่งจะทำให้เกิดเหตุการณ์ Session_OnEnd หากแอปพลิเคชันดำเนินการจัดการเซสชันผ่านส่วนประกอบที่ไม่อยู่ในกระบวนการ เหตุการณ์สิ้นสุดจะไม่เกิดขึ้น
เซสชันที่ไม่มีคุกกี้
แต่ละเซสชัน ASP.NET ที่ใช้งานอยู่จะถูกระบุโดยใช้สตริง 120 บิตซึ่งประกอบด้วยอักขระที่อนุญาตโดย URL เท่านั้น รหัสเซสชันถูกสร้างขึ้นโดยใช้ผู้ให้บริการเข้ารหัสลับตัวสร้างตัวเลขสุ่ม (RNG) ผู้ให้บริการส่งคืนลำดับตัวเลขที่สร้างขึ้นแบบสุ่ม 15 หมายเลข (15 ไบต์ x 8 บิต = 120 บิต) จากนั้นอาร์เรย์ของตัวเลขสุ่มจะถูกแมปกับอักขระ URL ที่ถูกต้องและส่งกลับเป็นสตริง
สตริง ID เซสชันจะถูกส่งไปยังเบราว์เซอร์และส่งคืนไปยังแอปพลิเคชันเซิร์ฟเวอร์ด้วยวิธีใดวิธีหนึ่งจากสองวิธี: การใช้คุกกี้ (เช่นเดียวกับใน ASP ดั้งเดิม) หรือ URL ที่ได้รับการแก้ไข ตามค่าเริ่มต้น โมดูลสถานะเซสชันจะสร้างคุกกี้ HTTP บนฝั่งไคลเอ็นต์ แต่สามารถใช้ URL ที่แก้ไขซึ่งฝังสตริง ID เซสชันไว้ได้ (โดยเฉพาะสำหรับเบราว์เซอร์ที่ไม่รองรับคุกกี้) วิธีการที่ใช้จะขึ้นอยู่กับการตั้งค่าคอนฟิกูเรชันที่จัดเก็บไว้ในไฟล์ web.config ของแอปพลิเคชัน หากต้องการกำหนดการตั้งค่าเซสชัน คุณสามารถใช้ส่วน <sessionState> และแอตทริบิวต์ที่ไม่มีคุกกี้
<sessionState cookieless="true|false" />;
โดยค่าเริ่มต้น แอตทริบิวต์ Cookieless จะเป็นเท็จ ซึ่งบ่งชี้ว่ามีการใช้คุกกี้ ที่จริงแล้ว คุกกี้เป็นเพียงไฟล์ข้อความที่เว็บเพจวางไว้บนฮาร์ดไดรฟ์ของลูกค้า ใน ASP.NET คุกกี้จะแสดงโดยอินสแตนซ์ของคลาส HttpCookie โดยทั่วไปแล้ว คุกกี้ประกอบด้วยชื่อ ชุดของค่า และเวลาหมดอายุ เมื่อตั้งค่าแอตทริบิวต์ Cookieless เป็นเท็จ โมดูลสถานะเซสชันจะสร้างคุกกี้ชื่อ ASP.NET_SessionId และจัดเก็บ ID เซสชันไว้ในนั้น รหัสเทียมต่อไปนี้แสดงกระบวนการสร้างคุกกี้:
HttpCookie sessionCookie;
sessionCookie = HttpCookie ใหม่ ("ASP.NET_SessionId", sessionID);
sessionCookie.Path = "/";
เวลาหมดอายุของคุกกี้เซสชันนั้นสั้นมาก และเวลาหมดอายุจะได้รับการอัปเดตหลังจากแต่ละคำขอสำเร็จ คุณลักษณะ Expires ของคุกกี้ระบุเวลาหมดอายุของคุกกี้บนไคลเอนต์ หากไม่ได้ตั้งค่าคุกกี้เซสชันอย่างชัดเจน คุณสมบัติ Expires จะมีค่าเริ่มต้นเป็น DateTime.MinValue ซึ่งเป็นหน่วยเวลาที่น้อยที่สุดที่ .NET Framework อนุญาต
หากต้องการปิดใช้งานคุกกี้เซสชัน ให้ตั้งค่าแอตทริบิวต์ Cookieless เป็น true ในไฟล์การกำหนดค่าดังนี้:
<configuration>;
<system.เว็บ>;
<sessionState Cookieless="true" />;
</system.web><;
</configuration><;
ณ จุดนี้ สมมติว่าคุณร้องขอเพจที่ URL ต่อไปนี้:
http://www.contoso.com/sample.aspx
เนื้อหาจริงที่แสดงในแถบที่อยู่ของเบราว์เซอร์จะแตกต่างออกไป และตอนนี้มีรหัสเซสชัน ดังต่อไปนี้ แสดงใน:
http://www.contoso.com/(5ylg0455mrvws1uz5mmaau45)/sample.aspx
เมื่อสร้างอินสแตนซ์โมดูล HTTP สถานะเซสชัน โมดูลจะตรวจสอบค่าของแอตทริบิวต์ที่ไม่มีคุกกี้ หากเป็นจริง ให้เปลี่ยนเส้นทางคำขอ (HTTP 302) ไปยัง URL เสมือนที่แก้ไขซึ่งมีรหัสเซสชันที่อยู่หน้าชื่อหน้าทันที เมื่อคำขอได้รับการประมวลผลอีกครั้ง รหัสเซสชันจะถูกรวมไว้ในคำขอ หากมีการร้องขอเพื่อเริ่มเซสชันใหม่ โมดูล HTTP จะสร้าง ID เซสชันใหม่ จากนั้นเปลี่ยนเส้นทางคำขอ หากมีการโพสต์คำขอกลับ แสดงว่ารหัสเซสชันนั้นมีอยู่แล้วเนื่องจากการย้อนกลับใช้ URL ที่เกี่ยวข้อง
ข้อเสียของการใช้เซสชันที่ไม่มีคุกกี้คือสถานะของเซสชันจะหายไปหากมีการเรียก URL ที่สมบูรณ์ เมื่อใช้คุกกี้ คุณสามารถล้างแถบที่อยู่ ไปที่แอปพลิเคชันอื่น จากนั้นกลับสู่แอปพลิเคชันก่อนหน้าและรับค่าเซสชันเดียวกัน หากคุณทำเช่นนี้ในขณะที่คุกกี้เซสชันถูกปิดใช้งาน ข้อมูลเซสชันจะสูญหาย ตัวอย่างเช่น โค้ดต่อไปนี้จะขัดจังหวะเซสชัน:
<a runat="server" href="/code/page.aspx">;คลิก</a>;
หากคุณต้องการใช้ URL ที่สมบูรณ์ โปรดใช้เทคนิคบางอย่างเพื่อ เปลี่ยนรหัสเซสชันที่เพิ่มลงใน URL ด้วยตนเอง คุณสามารถเรียกใช้เมธอด ApplyAppPathModifier บนคลาส HttpResponse
<a runat = "เซิร์ฟเวอร์"
href=<% =Response.ApplyAppPathModifier("/code/page.aspx"%><; >;Click</a>;
วิธีการ ApplyAppPathModifier จะใช้สตริงที่แสดงถึง URL และส่งคืน URL สัมบูรณ์ที่ฝังข้อมูลเซสชัน เทคนิคนี้มีประโยชน์อย่างยิ่ง เช่น เมื่อคุณต้องการเปลี่ยนเส้นทางจากหน้า HTTP ไปยังหน้า HTTPS
เดิมทีสถานะเซสชันสรุป
ถูกนำมาใช้กับ ASP แบบดั้งเดิมในฐานะ API ที่ใช้พจนานุกรมซึ่งช่วยให้นักพัฒนาสามารถจัดเก็บข้อมูลที่กำหนดเองในระหว่างเซสชันได้ ใน ASP.NET สถานะเซสชันรองรับคุณสมบัติหลักสองประการ: การจัดเก็บและถ่ายโอน ID เซสชันแบบไม่มีคุกกี้ และผู้ให้บริการสถานะที่จัดเก็บข้อมูลเซสชันจริง เมื่อต้องการใช้ความสามารถใหม่ทั้งสองนี้ ASP.NET ใช้ประโยชน์จากโมดูล HTTP เพื่อควบคุมการเชื่อมโยงระหว่างสถานะเซสชันและบริบทของคำขอที่กำลังประมวลผล
ใน ASP แบบดั้งเดิม การใช้สถานะเซสชันหมายถึงการใช้คุกกี้ กรณีนี้จะไม่เป็นเช่นนั้นใน ASP.NET อีกต่อไป เนื่องจากสามารถใช้สถาปัตยกรรมแบบไม่มีคุกกี้ได้ ด้วยประสิทธิภาพของโมดูล HTTP URL ที่ร้องขอสามารถถูกแยกย่อยเพื่อให้มี ID เซสชันแล้วเปลี่ยนเส้นทาง ถัดไป โมดูล HTTP จะแยก ID เซสชันออกจาก URL และใช้เพื่อดึงข้อมูลสถานะที่เก็บไว้
สถานะทางกายภาพของเซสชันสามารถจัดเก็บไว้ในสามตำแหน่ง: หน่วยความจำระหว่างดำเนินการ หน่วยความจำอยู่นอกกระบวนการ และตาราง SQL Server ข้อมูลจะต้องถูกทำให้เป็นอนุกรม/ดีซีเรียลไลซ์ก่อนที่แอปพลิเคชันจะสามารถใช้งานได้ โมดูล HTTP คัดลอกค่าเซสชันจากผู้ให้บริการไปยังหน่วยความจำของแอปพลิเคชันเมื่อเริ่มต้นคำขอ หลังจากคำขอเสร็จสิ้น สถานะที่แก้ไขจะถูกส่งกลับไปยังผู้ให้บริการ การสื่อสารข้อมูลนี้จะมีผลข้างเคียงที่แตกต่างกันไปตามประสิทธิภาพ แต่จะช่วยเพิ่มความน่าเชื่อถือและความมั่นคงอย่างมากและให้การสนับสนุนสำหรับเว็บฟาร์มและสถาปัตยกรรมเว็บในสวนที่ใช้งานง่ายขึ้น