อัปเดต
เนื่องจากคำตอบนี้มีวิธีแก้ปัญหาฉันจะไม่แก้ไข แต่ฉันพบวิธีที่สะอาดกว่ามากในการแก้ปัญหานี้ ดูคำตอบอื่น ๆ ของฉันสำหรับรายละเอียด ...
คำตอบเดิม:
ฉันคิดว่าทำไมจึงApplication_Error()
ไม่เรียกใช้วิธีการ ...
Global.asax.cs
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute()); // this line is the culprit
}
...
}
ตามค่าเริ่มต้น (เมื่อสร้างโปรเจ็กต์ใหม่) แอปพลิเคชัน MVC จะมีตรรกะบางอย่างในGlobal.asax.cs
ไฟล์ ตรรกะนี้ใช้สำหรับการแมปเส้นทางและการลงทะเบียนตัวกรอง โดยค่าเริ่มต้นจะลงทะเบียนเพียงตัวกรองเดียว: HandleErrorAttribute
ตัวกรอง เมื่อ customErrors เปิดอยู่ (หรือผ่านการร้องขอระยะไกลเมื่อตั้งค่าเป็น RemoteOnly) HandleErrorAttribute จะบอกให้ MVC มองหามุมมองข้อผิดพลาดและจะไม่เรียกใช้Application_Error()
เมธอด ฉันไม่สามารถหาเอกสารนี้ แต่ก็มีการอธิบายในคำตอบนี้บน programmers.stackexchange.com
ที่จะได้รับ ApplicationError () วิธีการเรียกร้องให้ทุกคนยกเว้น unhandled เอาง่ายๆบรรทัดที่ลงทะเบียนกรอง HandleErrorAttribute
ตอนนี้ปัญหาคือ: กำหนดค่า customErrors อย่างไรให้ได้สิ่งที่ต้องการ ...
customErrors redirectMode="ResponseRedirect"
ส่วนค่าเริ่มต้น คุณสามารถระบุแอตทริบิวต์ defaultRedirect ให้เป็นเส้นทาง MVC ได้เช่นกัน ฉันสร้าง ErrorController ซึ่งง่ายมากและเปลี่ยน web.config ของฉันให้เป็นแบบนี้ ...
web.config
<customErrors mode="RemoteOnly" redirectMode="ResponseRedirect" defaultRedirect="~/Error">
<error statusCode="404" redirect="~/Error/PageNotFound" />
</customErrors>
ปัญหาในการแก้ปัญหานี้คือ 302 เปลี่ยนเส้นทางไปยัง URL ข้อผิดพลาดของคุณจากนั้นหน้าเหล่านั้นจะตอบสนองด้วยรหัสสถานะ 200 สิ่งนี้ทำให้ Google จัดทำดัชนีหน้าข้อผิดพลาดซึ่งไม่ดี นอกจากนี้ยังไม่สอดคล้องกับข้อกำหนด HTTP มากนัก สิ่งที่ฉันต้องการทำไม่ใช่การเปลี่ยนเส้นทางและแทนที่การตอบกลับเดิมด้วยมุมมองข้อผิดพลาดที่กำหนดเอง
redirectMode="ResponseRewrite"
ผมพยายามที่จะเปลี่ยน น่าเสียดายที่ตัวเลือกนี้ไม่รองรับเส้นทาง MVCเฉพาะเพจ HTML แบบคงที่หรือ ASPX ฉันพยายามใช้หน้า HTML แบบคงที่ในตอนแรก แต่โค้ดตอบกลับยังคงเป็น 200 แต่อย่างน้อยก็ไม่เปลี่ยนเส้นทาง จากนั้นฉันก็ได้แนวคิดจากคำตอบนี้ ...
ฉันตัดสินใจเลิกใช้ MVC เพื่อจัดการข้อผิดพลาด ฉันสร้างError.aspx
ไฟล์PageNotFound.aspx
. และไฟล์. หน้าเหล่านี้เรียบง่ายมาก แต่มีเวทมนตร์ชิ้นเดียว ...
<script type="text/C#" runat="server">
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Response.StatusCode = (int) System.Net.HttpStatusCode.InternalServerError;
}
</script>
บล็อกนี้จะบอกหน้าที่ให้บริการด้วยรหัสสถานะที่ถูกต้อง ของหยาบบนเพจ PageNotFound.aspx ฉันใช้HttpStatusCode.NotFound
แทน ฉันเปลี่ยน web.config เป็นแบบนี้ ...
<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx">
<error statusCode="404" redirect="~/PageNotFound.aspx" />
</customErrors>
ทุกอย่างทำงานได้อย่างสมบูรณ์แบบ!
สรุป:
- ลบบรรทัด:
filters.Add(new HandleErrorAttribute());
- ใช้
Application_Error()
วิธีการบันทึกข้อยกเว้น
- ใช้ customErrors กับ ResponseRewrite โดยชี้ไปที่เพจ ASPX
- ทำให้เพจ ASPX รับผิดชอบโค้ดสถานะการตอบกลับของตนเอง
มีข้อเสียสองสามประการที่ฉันสังเกตเห็นด้วยวิธีนี้
- หน้า ASPX ไม่สามารถแชร์มาร์กอัปกับเทมเพลต Razor ได้ฉันต้องเขียนมาร์กอัปส่วนหัวและส่วนท้ายมาตรฐานของเว็บไซต์ของเราใหม่เพื่อให้ได้รูปลักษณ์และความรู้สึกที่สอดคล้องกัน
- หน้า * .aspx สามารถเข้าถึงได้โดยตรงโดยการกดปุ่ม URL
มีวิธีแก้ไขสำหรับปัญหาเหล่านี้ แต่ฉันไม่ได้กังวลมากพอที่พวกเขาจะทำงานพิเศษใด ๆ
ฉันหวังว่านี่จะช่วยทุกคน!