สำหรับเว็บแอปพลิเคชัน ข้อผิดพลาดเป็นสิ่งที่หลีกเลี่ยงไม่ได้ ดังนั้นเราจึงควรใช้ความระมัดระวังและให้การจัดการที่เหมาะสมสำหรับข้อผิดพลาดที่อาจเกิดขึ้น ที่จริงแล้ว กลไกการจัดการข้อผิดพลาดที่ดีถือเป็นเกณฑ์สำคัญในการวัดคุณภาพของเว็บแอปพลิเคชัน ลองนึกภาพว่าเมื่อผู้ใช้ป้อน URL ผิดในเบราว์เซอร์โดยไม่ได้ตั้งใจหรือเมื่อผู้ใช้ให้ข้อมูลบางอย่างที่ทำให้โปรแกรมเกิดข้อผิดพลาดหากเราไม่จัดการกับสถานการณ์เหล่านี้เราจะอนุญาตให้มีหน้าข้อผิดพลาด 404 หรือ 500 หรือแม้แต่ข้อผิดพลาดข้อมูลสแต็ก ปรากฏต่อหน้าผู้ใช้ ซึ่งจะทำให้ผู้ใช้บางคนกลัวอย่างแน่นอน ดังนั้นเมื่อเราพัฒนาเว็บแอปพลิเคชัน เราควรมีความเข้าใจอย่างถ่องแท้เกี่ยวกับกลไกการจัดการข้อผิดพลาด
กลับไปที่ ASP.NET และถามคำถามสองข้อเพื่อให้ทุกคนนึกถึง: ASP.NET มีกลไกการจัดการข้อผิดพลาดกี่ข้อให้เรา? หากมีการใช้กลไกการจัดการข้อผิดพลาดหลายอย่างพร้อมกัน มีลำดับความสำคัญที่แน่นอนระหว่างกลไกเหล่านั้นหรือไม่ เมื่อมีคำถามนี้ เรามาลองดูไฟล์ Web.Config ที่พบบ่อยที่สุดของเรา:
<?xml version="1.0"?>
<การกำหนดค่า>
<system.เว็บ>
<customErrors mode="On" defaultRedirect="GenericErrorPage.htm">
<สถานะข้อผิดพลาดรหัส = "403" เปลี่ยนเส้นทาง = "Error403.htm" / >
<สถานะข้อผิดพลาด = "404" เปลี่ยนเส้นทาง = "Error404.htm" / >
</ข้อผิดพลาดแบบกำหนดเอง>
</system.เว็บ>
</การกำหนดค่า>
เกี่ยวกับรายการการตั้งค่า <customErrors> ฉันคิดว่าไม่จำเป็นต้องพูดอะไรเพิ่มเติม สำหรับรายละเอียด โปรดดูที่ MSDN กลไกการจัดการข้อผิดพลาดแรก - การใช้รายการการกำหนดค่า <customErrors> ของ Web.Config ควรเป็นกลไกที่ใช้บ่อยที่สุด
ต่อไป มาดูไฟล์อื่นที่ใช้กันทั่วไปเช่นกัน: Global.asax เมื่อพูดถึงเอกสารนี้ คุณนึกถึงอะไร? ใช่ เป็นเหตุการณ์ที่เกี่ยวข้องกับออบเจ็กต์แอปพลิเคชันเว็บหลักสองรายการ (แอปพลิเคชันและเซสชัน) ในบรรดาเหตุการณ์เหล่านี้ มีเหตุการณ์ที่เกี่ยวข้องกับข้อผิดพลาดซึ่งอยู่ในหมวดหมู่แอปพลิเคชัน - ข้อผิดพลาด และวิธีการประมวลผลเหตุการณ์ที่เกี่ยวข้องคือ Application_Error ตามชื่อที่แนะนำ วิธีการจัดการเหตุการณ์นี้จะถูกเรียกเมื่อมีข้อผิดพลาดระดับแอปพลิเคชันเกิดขึ้น ดังนั้นคุณสามารถเพิ่มโค้ดในวิธีนี้เพื่อจัดการกับข้อผิดพลาด ดังที่แสดงด้านล่าง:
protected void Application_Error(object sender, EventArgs e) {
ข้อยกเว้น objErr = Server.GetLastError().GetBaseException();
Response.Write("ข้อผิดพลาด:" + objErr.Message);
เซิร์ฟเวอร์ ClearError();
}
ที่นี่ ทุกคนควรใส่ใจกับการใช้ Server.ClearError() ในโค้ดบรรทัดสุดท้าย เพราะเหตุใดจึงควรใช้โค้ดบรรทัดนี้ จะเกิดอะไรขึ้นถ้าคุณไม่ใช้มัน? ที่นี่ฉันจะลองอีกครั้ง กลไกการจัดการข้อผิดพลาดประการที่สองซึ่งใช้วิธีจัดการเหตุการณ์ Application_Error ใน Global.asax ก็ได้เปิดตัวเช่นกัน
วิธีการจัดการข้อผิดพลาดสองวิธีข้างต้นอาจกล่าวได้ว่าเป็นสากล วิธีหนึ่งได้มาจากไฟล์การกำหนดค่าแอปพลิเคชัน และอีกวิธีหนึ่งคือวิธีการจัดการเหตุการณ์ของไฟล์ Global.asax ที่ต้องวางไว้ในไดเร็กทอรีรากของแอปพลิเคชัน สิ่งที่ตรงกันข้ามกับระดับโลกคือในท้องถิ่น ดังนั้นเราจึงสงสัยว่า: มีกลไกการจัดการข้อผิดพลาดที่นำไปใช้กับท้องถิ่น - หน้าเว็บบางหน้าหรือไม่ คำตอบคือ "ใช่" และมีสองวิธี - การใช้แอตทริบิวต์ ErrorPage และการใช้วิธีการจัดการเหตุการณ์ Page_Error สำหรับกลไกแรก คุณสามารถตั้งค่าคุณสมบัติ ErrorPage ได้เกือบตลอดเวลาเพื่อกำหนดว่าเพจใดจะถูกเปลี่ยนเส้นทางไปเมื่อมีข้อผิดพลาดเกิดขึ้นบนเพจ สำหรับกลไกที่สอง จะคล้ายกับวิธีการจัดการเหตุการณ์ Application_Error มาก ยกเว้นแต่ว่า จังหวะเวลาของการถูกกระตุ้นนั้นแตกต่างกัน ต่อไปนี้เป็นตัวอย่างสองตัวอย่าง:
<script language="C#" runat="server">
โมฆะที่ได้รับการป้องกัน Page_Load (ผู้ส่งวัตถุ EventArgs e) {
this.ErrorPage = "ErrorPage.htm";
-
</สคริปต์>
ป้องกันเป็นโมฆะ Page_Error (ผู้ส่งวัตถุ EventArgs e) {
ข้อยกเว้น objErr = Server.GetLastError().GetBaseException();
Response.Write("ข้อผิดพลาด:" + objErr.Message);
Server.ClearError(); //โปรดใส่ใจกับการใช้โค้ดนี้ด้วย
}
ณ จุดนี้ กลไกการจัดการข้อผิดพลาดทั้งสี่ได้ปรากฏขึ้นแล้ว และถึงเวลาที่จะจัดอันดับกลไกเหล่านั้น เรียงลำดับจากลำดับความสำคัญสูงไปต่ำ: วิธีการจัดการเหตุการณ์ Page_Error > คุณสมบัติ ErrorPage > วิธีการจัดการเหตุการณ์ Application_Error > รายการการกำหนดค่า <customErrors> แม้ว่าการจัดอันดับจะเป็นเช่นนี้ แต่ก็มีความสัมพันธ์ที่ละเอียดอ่อนระหว่างการจัดอันดับ ก่อนอื่น เพื่อให้แอตทริบิวต์ ErrorPage ทำงาน แอตทริบิวต์โหมดในรายการการกำหนดค่า <customErrors> จะต้องตั้งค่าเป็น "เปิด" ประการที่สอง แม้ว่าวิธีการประมวลผลเหตุการณ์ Page_Error จะได้รับการจัดอันดับเป็นอันดับแรก หากเมธอด Server.ClearError() เป็น หายไป หากเป็นเช่นนั้น การจัดการข้อผิดพลาดที่มีลำดับความสำคัญต่ำกว่าจะยังคงถูกทริกเกอร์ ซึ่งก็เป็นจริงสำหรับวิธีการจัดการเหตุการณ์ Application_Error มีการจัดเรียงคำสั่งซื้อ แต่คำสั่งซื้อไม่ใช่ประเด็นที่สำคัญที่สุด อาจเรียกได้ว่าเป็นปัญหาที่ไม่มีความหมายมากนัก เพราะในหลายกรณี คุณอาจไม่ได้ใช้กลไกการประมวลผลทั้งสี่นี้ผสมกัน ฉันคิดว่าปัญหาที่สำคัญที่สุดคือวิธีการเลือกกลไกการจัดการข้อผิดพลาดเหล่านี้ ในประเด็นนี้ ผมหวังว่าเพื่อนๆ ที่มีประสบการณ์จะมาแบ่งปันความคิดเห็นกัน
เอาล่ะ นี่เป็นการแนะนำกลไกการจัดการข้อผิดพลาดสี่ประการของ ASP.NET และถึงเวลาที่จะพูดถึงความรู้สึกของตัวเองบ้าง ผู้ออกแบบ ASP.NET ได้พิจารณาอย่างรอบคอบจากมุมมองของนักพัฒนาแล้ว ดังนั้นพวกเขาจึงจัดเตรียมกลไกการจัดการข้อผิดพลาดมากถึงสี่กลไกให้เราเลือก ซึ่งถือเป็นเรื่องน่ายกย่อง แต่ในการถอดความสโลแกนโฆษณา - มากเกินไปทำให้เกิดความสับสน เรายังจะเวียนหัวเล็กน้อยด้วยกลไกการจัดการข้อผิดพลาดมากมาย เมื่อเปรียบเทียบการจัดการข้อผิดพลาดในฟิลด์ J2EE เราพบว่ามันค่อนข้างง่าย อย่างแรกคือการตั้งค่าที่สอดคล้องกับ <customErrors> นอกจากนี้เรายังสามารถค้นหารายการการกำหนดค่าที่คล้ายกันจากไฟล์ web.xml ที่ใช้บ่อยที่สุดในโปรเจ็กต์ J2EE: ประการที่สองในฟิลด์ของ J2EE หน้าไม่ใช่เอนทิตีที่สำคัญและ เหตุการณ์ ไม่จำเป็นต้องใช้โมเดลไดรเวอร์ ดังนั้นฉันจึงไม่พบกลไกการประมวลผลที่เกี่ยวข้องสำหรับเมธอด Application_Error และ Page_Error ในที่สุด ในด้าน J2EE ก็จะมีการเน้นไปที่คำขอและการตอบกลับมากขึ้น เมื่อเกิดข้อผิดพลาดในการประมวลผลเชิงตรรกะ เราสามารถกระจาย Request ไปยังโมดูลการจัดการข้อผิดพลาดที่เกี่ยวข้องได้อย่างง่ายดายผ่าน RequestDispatcher อันที่จริง นี่เป็นวิธีการประมวลผลที่ยืดหยุ่นมาก เพื่อนๆ ที่สนใจอาจต้องการเรียนรู้เกี่ยวกับเรื่องนี้