คำตอบด่วน / TL; DR
สำหรับคนขี้เกียจที่นั่น:
Install-Package MagicalUnicornMvcErrorToolkit -Version 1.0
จากนั้นลบบรรทัดนี้ออก global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
และนี่สำหรับ IIS7 + และ IIS Express เท่านั้น
หากคุณกำลังใช้ Cassini .. ดี .. เอ่อ .. เอ่อ .. อึดอัด ...
ยาวอธิบายคำตอบ
ฉันรู้ว่าสิ่งนี้ได้รับคำตอบแล้ว แต่คำตอบนั้นง่ายจริงๆ (ให้กำลังใจกับDavid FowlerและDamian Edwardsสำหรับการตอบคำถามนี้จริงๆ)
มีความต้องการที่จะทำอะไรที่กำหนดเองไม่มี
สำหรับASP.NET MVC3
บิตและชิ้นส่วนทั้งหมดอยู่ที่นั่น
ขั้นตอนที่ 1 -> อัปเดต web.config ของคุณในสองจุด
<system.web>
<customErrors mode="On" defaultRedirect="/ServerError">
<error statusCode="404" redirect="/NotFound" />
</customErrors>
และ
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/NotFound" responseMode="ExecuteURL" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="500" path="/ServerError" responseMode="ExecuteURL" />
</httpErrors>
...
<system.webServer>
...
</system.web>
ตอนนี้จดบันทึก ROUTES ที่ฉันตัดสินใจใช้อย่างระมัดระวัง คุณสามารถใช้อะไรก็ได้ แต่เส้นทางของฉันคือ
/NotFound
<- สำหรับ 404 ไม่พบหน้าข้อผิดพลาด
/ServerError
<- สำหรับข้อผิดพลาดอื่น ๆ รวมถึงข้อผิดพลาดที่เกิดขึ้นในรหัสของฉัน นี่เป็นข้อผิดพลาดเซิร์ฟเวอร์ภายใน 500 ข้อ
ดูว่าส่วนแรก<system.web>
มีเพียงรายการเดียวที่กำหนดเองได้อย่างไร statusCode="404"
รายการ? ฉันระบุรหัสสถานะเพียงรหัสเดียวเนื่องจากข้อผิดพลาดอื่น ๆ ทั้งหมดรวมถึง500 Server Error
(เช่นข้อผิดพลาดที่น่ารำคาญที่เกิดขึ้นเมื่อรหัสของคุณมีข้อผิดพลาดและขัดข้องคำขอของผู้ใช้) .. ข้อผิดพลาดอื่น ๆ ทั้งหมดได้รับการจัดการโดยการตั้งค่าdefaultRedirect="/ServerError"
.. หากคุณไม่พบหน้า 404 กรุณาข้ามเส้นทาง/ServerError
ไป
ตกลง. มันออกนอกเส้นทางไปยังเส้นทางของฉันที่ระบุไว้global.asax
ขั้นตอนที่ 2 - การสร้างเส้นทางใน Global.asax
นี่คือส่วนเส้นทางแบบเต็มของฉัน ..
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new {favicon = @"(.*/)?favicon.ico(/.*)?"});
routes.MapRoute(
"Error - 404",
"NotFound",
new { controller = "Error", action = "NotFound" }
);
routes.MapRoute(
"Error - 500",
"ServerError",
new { controller = "Error", action = "ServerError"}
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
}
นั่นแสดงเส้นทางที่ไม่สนใจสองเส้นทาง -> axd's
และfavicons
(ooo! bonus เพิกเฉยเส้นทางสำหรับคุณ!) จากนั้น (และคำสั่งนั้นใช้งานได้ที่นี่) ฉันมีเส้นทางการจัดการข้อผิดพลาดสองเส้นทางที่ชัดเจน .. ตามด้วยเส้นทางอื่น ๆ ในกรณีนี้เป็นค่าเริ่มต้น แน่นอนว่าฉันมีมากกว่านี้ แต่พิเศษสำหรับเว็บไซต์ของฉัน เพียงตรวจสอบให้แน่ใจว่าเส้นทางข้อผิดพลาดอยู่ด้านบนของรายการ สั่งซื้อสินค้าที่มีความจำเป็น
สุดท้ายในขณะที่เราอยู่ในglobal.asax
ไฟล์ของเราเราไม่ได้ลงทะเบียนคุณลักษณะ HandleError ทั่วโลก ไม่ไม่ไม่ครับ Nadda Nope Nien เชิงลบ noooooooooo ...
ลบบรรทัดนี้ออก global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
ขั้นตอนที่ 3 - สร้างตัวควบคุมด้วยวิธีการดำเนินการ
ตอนนี้ .. เราเพิ่มตัวควบคุมด้วยวิธีการสองวิธี ...
public class ErrorController : Controller
{
public ActionResult NotFound()
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
public ActionResult ServerError()
{
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
// Todo: Pass the exception into the view model, which you can make.
// That's an exercise, dear reader, for -you-.
// In case u want to pass it to the view, if you're admin, etc.
// if (User.IsAdmin) // <-- I just made that up :) U get the idea...
// {
// var exception = Server.GetLastError();
// // etc..
// }
return View();
}
// Shhh .. secret test method .. ooOOooOooOOOooohhhhhhhh
public ActionResult ThrowError()
{
throw new NotImplementedException("Pew ^ Pew");
}
}
ตกลงให้ตรวจสอบนี้ ก่อนอื่นไม่มีแอ [HandleError]
ททริบิวต์ที่นี่ ทำไม? เนื่องจากASP.NET
เฟรมเวิร์กในตัวจัดการข้อผิดพลาดอยู่แล้วและเราได้ระบุอึทั้งหมดที่เราต้องทำเพื่อจัดการข้อผิดพลาด :) มันอยู่ในวิธีนี้!
ต่อไปฉันมีสองวิธีในการดำเนินการ ไม่มีอะไรยาก หากคุณต้องการแสดงข้อมูลข้อยกเว้นคุณสามารถใช้Server.GetLastError()
เพื่อรับข้อมูลนั้นได้
โบนัส WTF: ใช่ฉันได้ทำวิธีที่สามเพื่อทดสอบการจัดการข้อผิดพลาด
ขั้นตอนที่ 4 - สร้างมุมมอง
และสุดท้ายสร้างสองมุมมอง วาง em ในมุมมองปกติสำหรับคอนโทรลเลอร์นี้
ความคิดเห็นโบนัส
- คุณไม่ต้องการ
Application_Error(object sender, EventArgs e)
- ดังกล่าวข้างต้นขั้นตอนการทำงานทั้งหมด 100% อย่างสมบูรณ์แบบด้วยELMAH Elmah เต็มไปด้วย wroxs!
และที่เพื่อนของฉันควรจะเป็น
ตอนนี้ขอแสดงความยินดีกับการอ่านมากและมีรางวัลยูนิคอร์น!