วัตถุประสงค์:
ตระหนักถึงการใช้ไฟล์ .cs ใน MasterPage เพื่อแทนที่ PageBase ในโครงการ
แรงจูงใจ:
แรงจูงใจในการเขียนบทความนี้มาจากการบูรณะโครงการใหม่ ในโครงการสถาปัตยกรรม B/S ของ .Net Framwork 2.0 มีการใช้ทั้งเทคโนโลยี PageBase และ MasterPage พบว่าทุกครั้งที่มีการเข้าถึงเพจ เพจจะเข้าถึง PageBase และ MasterPage ในเวลาเดียวกัน ซึ่งไม่เพียงทำให้ประสิทธิภาพลดลงเท่านั้น แต่อาจทำให้เกิดปัญหาในการขยายและปรับเปลี่ยนฟังก์ชันโครงการในอนาคตได้
ด้านเทคนิค:
PageBase: เทคโนโลยีที่มักใช้ใน .Net Framework 1.1 เพื่อสรุปฟังก์ชันการทำงานเดียวกันของหลายเพจ คลาส PageBase.cs สืบทอดมาจากคลาส System.Web.UI.Page เว็บเพจในโครงการสืบทอดมาจากคลาส PageBase.cs โดยการแทนที่วิธีการเริ่มต้นเพจในคลาสพื้นฐาน ฟังก์ชันทางธุรกิจใน PageBase จะถูกเรียก เช่น: พารามิเตอร์ url การตรวจสอบ การบันทึกการเข้าชม และฟังก์ชันอื่นๆ (สำหรับวิธีการใช้งานเฉพาะ โปรดดู duwamishi ตัวอย่างอย่างเป็นทางการของ Microsoft)
MasterPage: คุณลักษณะใหม่ใน .Net Framework 2.0 โดยทางกายภาพประกอบด้วยสองไฟล์: ไฟล์ .Master (มาร์กอัป html) และไฟล์ .cs (รหัส C#) ไฟล์ .Master ใช้การวาดเลเยอร์การแสดงผล และไฟล์ .cs ใช้ฟังก์ชันเฉพาะ เว็บเพจที่สืบทอดมาจาก MasterPage สามารถสืบทอดเนื้อหาเลเยอร์การแสดงผลใน MasterPage ได้ หากต้องการวาดส่วนหัวและส่วนท้ายร่วมกันและปรับแต่งเค้าโครงแบบรวม MasterPage เป็นตัวเลือกที่ดี
ข้อกำหนดการจำลอง:
ใช้เทคโนโลยี MasterPage เพื่อแทนที่ PageBase เพื่อใช้การตรวจสอบพารามิเตอร์แถบที่อยู่
ขออธิบายง่ายๆ ครับ ข้อมูลตาราง Login ในฐานข้อมูลมีดังนี้
หลังจากเข้าสู่ระบบแล้วจะมีพารามิเตอร์ในแถบที่อยู่ URL ดังนี้
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
ในขณะนี้ ผู้ใช้แก้ไขพารามิเตอร์ในแถบที่อยู่ URL ด้วยตนเองดังนี้:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
ถือเป็นการดำเนินการที่ผิดกฎหมายและระบบจะกระโดดกลับไปยังหน้าเข้าสู่ระบบโดยอัตโนมัติ
การวนซ้ำโค้ดครั้งแรก:
1. อ้างถึงวิธี PageBase แบบดั้งเดิม:
แนวทางเพจแบบดั้งเดิมคือ:
PageBase คลาสสาธารณะ: System.Web.UI.Page
-
สาธารณะเพจเบส()
-
-
/***////// <สรุป>
/// วิธีการเข้า
/// </สรุป>
โมฆะที่ได้รับการป้องกันเริ่มต้น ()
-
//ใส่ตรรกะทางธุรกิจทั่วไป
-
-
หน้าเว็บ:
TestPage คลาสสาธารณะบางส่วน: PageBase
-
//วิธีการเรียก PageBase แบบดั้งเดิม
/***/////// <สรุป>
/// แทนที่เมธอด OnPreInit() คลาสพื้นฐาน และเรียกใช้วิธีการตรวจสอบทั่วไป
/// </สรุป>
/// <ชื่อพารามิเตอร์ = "e" ></ พารามิเตอร์>
การป้องกันการแทนที่เป็นโมฆะ OnInit (เหตุการณ์ e)
-
ฐานเริ่มต้น();
-
-
ปฏิบัติตามแนวทางนี้และย้ายโค้ดใน PageBase ไปยัง MasterPage:
MasterPage.cs:
MyMasterPage คลาสสาธารณะบางส่วน: System.Web.UI.MasterPage
-
โมฆะที่ได้รับการป้องกัน Page_Load (ผู้ส่งวัตถุ EventArgs e)
-
ถ้า (!IsPostBack)
-
//วิธีการยืนยันการโทร
เริ่มต้น();
-
-
-
แก้ไขโค้ดในหน้าเว็บเป็น:
TestPage คลาสสาธารณะบางส่วน: System.Web.UI.Page
-
// เลียนแบบวิธี PageBase และเรียกใช้วิธีการใน Master
/***////// <สรุป>
/// แทนที่เมธอด OnPreInit() คลาสพื้นฐาน และเรียกใช้วิธีการตรวจสอบทั่วไป
/// </สรุป>
/// <ชื่อพารามิเตอร์ = "e" ></ พารามิเตอร์>
การป้องกันการแทนที่เป็นโมฆะ OnInit (เหตุการณ์ e)
-
// รับการอ้างอิงหน้าหลัก
MyMasterPage myMasterPage = (MyMasterPage)this.Master;
//เรียกวิธีการตรวจสอบทั่วไปในหน้าต้นแบบ
ถ้า (!IsPostBack)
-
myMasterPage.Initialize();
-
-
}แทนที่เมธอด Initialize() ใน MasterPage ด้วยเมธอดในอินสแตนซ์ รหัสทดสอบ:
ขั้นตอนที่ 1: เข้าสู่ระบบด้วยชื่อผู้ใช้ zhangsan และการเข้าสู่ระบบสำเร็จ
หน้านี้แสดงว่ายินดีต้อนรับเข้าสู่ zhangsan เข้าสู่ระบบ
ที่อยู่ URL จะแสดง:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
ขั้นตอนที่ 2: แก้ไขแถบที่อยู่ URL ด้วยตนเอง: ดังนี้:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
หน้านี้จะไม่แสดงการเข้าสู่ระบบ lisi ยินดีต้อนรับ แต่จะข้ามกลับไปที่หน้าการเข้าสู่ระบบ
การสะท้อนกลับ: แม้ว่าฟังก์ชันนี้จะถูกนำมาใช้ แต่ก็ยังมีลิงก์ที่ไม่น่าพึงพอใจอยู่บ้าง:
1. วิธีการที่ถูกเรียกโดยคลาสย่อยใน Master จะต้องเป็นวิธีการสาธารณะ
2. แม้ว่าไม่จำเป็นต้องแก้ไขการสืบทอดของเว็บเพจ แต่คุณยังคงต้องคัดลอกและวางและแทนที่เมธอด OnInit() ของคลาสพื้นฐานโดยอัตโนมัติ
เพื่อกำจัดความรู้สึกที่ค้างคาเหล่านี้ ฉันเริ่ม:
การวนซ้ำโค้ดที่สอง:
แก้ไขโค้ดใน MasterPage.cs:
MyMasterPage คลาสสาธารณะบางส่วน: System.Web.UI.MasterPage
-
โมฆะที่ได้รับการป้องกัน Page_Load (ผู้ส่งวัตถุ EventArgs e)
-
ถ้า (!IsPostBack)
-
//วิธีการยืนยันการโทร
ตรวจสอบเข้าสู่ระบบ();
-
-
/***////// <สรุป>
/// ตรวจสอบว่าการเข้าถึงนั้นถูกกฎหมายหรือไม่
/// </สรุป>
CheckLogin เป็นโมฆะส่วนตัว ()
-
// ถ้าเป็นตัวเลขใน url หรือตัวเลขในคุกกี้
ถ้า (string.IsNullOrEmpty(Request.QueryString["id"])
||. string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
-
Response.Redirect("เข้าสู่ระบบ.aspx");
}//หากตัวเลขใน url ไม่ตรงกับตัวเลขในคุกกี้ ให้กลับไปที่หน้าเข้าสู่ระบบ
อื่นถ้า (int.Parse(Request.QueryString["id"]) != int.Parse(CookieUtil.ReadCookieByKey("id")))
-
Response.Redirect("เข้าสู่ระบบ.aspx");
-
-
}หลังจากการสร้างใหม่ หน้าเว็บจะไม่สามารถแก้ไขได้ไม่ว่าด้วยวิธีใดก็ตาม MasterPage จะเรียกวิธีการตรวจสอบโดยอัตโนมัติด้วยวิธีการ Page_Load() ของตัวเอง และตั้งค่าวิธีการตรวจสอบเป็นแบบส่วนตัว ซึ่ง MasterPage เท่านั้นที่สามารถเรียกได้เพื่อปรับปรุงความปลอดภัย ณ จุดนี้ดูเหมือนว่าโค้ดจะเหมาะสมที่สุด ทดสอบ:
ขั้นตอนที่ 1: เข้าสู่ระบบด้วยชื่อผู้ใช้ zhangsan
หน้าเข้าสู่ระบบของผู้ใช้ยังคงแสดงอยู่
การทดสอบล้มเหลว
ใช้เบรกพอยต์เพื่อติดตามโค้ดและพบว่าปัญหาเกิดขึ้นในข้อมูลโค้ดในเมธอด CheckLogin() ใน MasterPage.cs:
ถ้า (string.IsNullOrEmpty(Request.QueryString["id"])
||. string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
-
Response.Redirect("เข้าสู่ระบบ.aspx");
-
เนื่องจากหน้าเข้าสู่ระบบสืบทอดมาจาก MasterPage วิธีการตรวจสอบใน MasterPage.cs จะถูกเรียกโดยอัตโนมัติเมื่อมีการโหลดหน้า และพารามิเตอร์ของตัวเองไม่เป็นไปตามเมธอด string.IsNullOrEmpty() ดังนั้นจึงข้ามกลับไปยังหน้าเข้าสู่ระบบ มีการโหลดหน้าอีกครั้ง วิธีการตรวจสอบในคลาสพื้นฐานเรียกว่า จึงสร้างการวนซ้ำไม่สิ้นสุด
ในเทคโนโลยี PageBase เว็บเพจสามารถเลือกสืบทอดจาก PageBase ได้ แต่ในเทคโนโลยี MasterPage เพื่อให้ได้เอฟเฟกต์เลเยอร์การแสดงผลที่สอดคล้องกัน การเลือกของเว็บเพจที่จะสืบทอด MasterPage นั้นต่ำมาก และเราไม่ควรสร้างการแสดงผลเดียวกันโดยการสร้าง ใหม่ , MasterPage ที่ไม่มีรหัสยืนยันใช้เพื่อสืบทอดหน้าเว็บที่ไม่จำเป็นต้องสืบทอดฟังก์ชันคลาสพื้นฐานอย่างเห็นได้ชัด เพื่อที่จะแก้ไขปัญหานี้ จึงได้เริ่มต้นการวนซ้ำครั้งที่สาม:
นำเข้าไฟล์การกำหนดค่า:
<?xml version="1.0" encoding="utf-8" ?>
<หน้า>
<หน้าทดสอบ>
<ชื่อหน้า = "TestPage" url = "TestPage.aspx" needvalidate = "true"/>
<ชื่อหน้า = "เข้าสู่ระบบ" url = "Login.aspx" needvalidate = "false"/>
</หน้าทดสอบ>
<หน้าผู้ดูแลระบบ>
<ชื่อหน้า = "Page1" url = "~/Admin/Page1.aspx" needvalidate = "false"/>
<ชื่อหน้า = "Page2" url = "~/Admin/Page2.aspx" needvalidate = "false"/>
</หน้าผู้ดูแลระบบ>
</หน้า>
อย่างที่คุณเห็น มีการระบุหน้าที่จำเป็นต้องตรวจสอบ (needvalidate="true")
สร้างคลาสการเข้าถึงข้อมูล XML:
XmlDAL คลาสสาธารณะ
-
filePath สตริงคงที่ส่วนตัว = string.Empty;
XmlDAL แบบคงที่ ()
-
// เริ่มต้นเส้นทางไฟล์การกำหนดค่า
filePath = HttpContext.Current.Request.MapPath("~/App_Data/xml/" + "Pages.xml");
-
/***////// <สรุป>
/// รับรายการเพจที่ต้องตรวจสอบ
/// </สรุป>
/// <returns>รายการหน้าที่ต้องมีการตรวจสอบ</returns>
สาธารณะ IList <string> GetValidatePages() แบบคงที่
-
IList<string> หน้า = รายการใหม่<string>();
// หากมีไฟล์การกำหนดค่าที่ระบุอยู่
ถ้า (System.IO.File.Exists (filePath))
-
พยายาม
-
XmlDocument xmlDoc = XmlDocument ใหม่();
xmlDoc.Load(เส้นทางไฟล์);
// รับโหนดรูทของไฟล์คอนฟิกูเรชัน
ราก XmlNode = xmlDoc.DocumentElement;
สตริง xpath = "/pages/testpage/page[@needvalidate='true']";
XmlNodeList nodeList = root.SelectNodes(xpath);
// การรวบรวมโหนดความสะดวกสบาย
foreach (โหนด XmlNode ใน nodeList)
-
หน้าเพิ่ม(node.Attributes["title"].Value);
-
-
catch (ข้อยกเว้น เช่น)
-
โยนข้อยกเว้นใหม่ (เช่นข้อความ);
-
-
กลับหน้า;
-
-
ปรับโครงสร้างโค้ดใน MasterPage.cs และเพิ่มเมธอด IsValidateNeeded(string url) เพื่อตรวจสอบว่าหน้าปัจจุบันต้องมีการตรวจสอบหรือไม่
MyMasterPage คลาสสาธารณะบางส่วน: System.Web.UI.MasterPage
-
โมฆะที่ได้รับการป้องกัน Page_Load (ผู้ส่งวัตถุ EventArgs e)
-
ถ้า (!IsPostBack)
-
//วิธีการยืนยันการโทร
ตรวจสอบเข้าสู่ระบบ();
-
-
/***////// <สรุป>
/// ตรวจสอบว่าการเข้าถึงนั้นถูกกฎหมายหรือไม่
/// </สรุป>
CheckLogin เป็นโมฆะส่วนตัว ()
-
// ตรวจสอบว่าหน้าที่เข้าถึงอยู่ในปัจจุบันต้องมีการตรวจสอบหรือไม่
ถ้า (IsValidateNeeded (Request.RawUrl))
-
// ถ้าเป็นตัวเลขใน url หรือตัวเลขในคุกกี้
ถ้า (string.IsNullOrEmpty(Request.QueryString["id"])
||. string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
-
Response.Redirect("เข้าสู่ระบบ.aspx");
}//หากตัวเลขใน url ไม่ตรงกับตัวเลขในคุกกี้ ให้กลับไปที่หน้าเข้าสู่ระบบ
อื่นถ้า (int.Parse(Request.QueryString["id"]) != int.Parse(CookieUtil.ReadCookieByKey("id")))
-
Response.Redirect("เข้าสู่ระบบ.aspx");
-
-
-
/***////// <สรุป>
/// ตรวจสอบว่าหน้าปัจจุบันต้องมีการตรวจสอบหรือไม่
/// </สรุป>
/// <param name="currentPage">ชื่อเพจปัจจุบัน</param>
/// <returns>ต้องตรวจสอบสถานะหรือไม่</returns>
บูลส่วนตัว IsValidateNeeded (URL สตริง)
-
บูล isNeeded = เท็จ;
// เมธอด GetValidatePages() ส่งคืนรายการเพจที่ต้องตรวจสอบ
IList<string> หน้า = XmlDAL.GetValidatePages();
IEnumerator<string> เช่น = หน้า GetEnumerator();
ในขณะที่ (เช่น MoveNext())
-
// หากหน้าปัจจุบันต้องมีการตรวจสอบ
ถ้า (url.Contains (เช่น. ปัจจุบัน))
//กลับสู่สถานะที่ต้องการการตรวจสอบ
return isNeeded = จริง;
-
จำเป็นต้องส่งคืน;
-
-
วิธีทดสอบ:
ขั้นตอนที่ 1: เข้าสู่ระบบด้วยชื่อผู้ใช้ zhangsan และการเข้าสู่ระบบสำเร็จ
หน้านี้แสดงว่ายินดีต้อนรับเข้าสู่ zhangsan เข้าสู่ระบบ
ที่อยู่ URL จะแสดง:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
ขั้นตอนที่ 2: แก้ไขแถบที่อยู่ URL ด้วยตนเอง: ดังนี้:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
หน้านี้จะไม่แสดงการเข้าสู่ระบบ lisi ยินดีต้อนรับ แต่จะข้ามกลับไปที่หน้าการเข้าสู่ระบบ
นี่เป็นการสรุปการวนซ้ำโค้ดของฉัน
ดาวน์โหลดรหัส: