วิธีทำให้หน้าข้อผิดพลาดที่กำหนดเองทำงานใน ASP.NET MVC 4


247

ฉันต้องการหน้าแสดงข้อผิดพลาดที่กำหนดเองสำหรับ 500, 404 และ 403 นี่คือสิ่งที่ฉันได้ทำ:

  1. ข้อผิดพลาดที่กำหนดเองที่เปิดใช้งานใน web.config ดังต่อไปนี้:

    <customErrors mode="On" 
                  defaultRedirect="~/Views/Shared/Error.cshtml">
    
        <error statusCode="403" 
               redirect="~/Views/Shared/UnauthorizedAccess.cshtml" />
    
        <error statusCode="404" 
               redirect="~/Views/Shared/FileNotFound.cshtml" />
    
    </customErrors>
  2. ลงทะเบียนHandleErrorAttributeเป็นตัวกรองการดำเนินการทั่วโลกในFilterConfigชั้นเรียนดังต่อไปนี้:

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CustomHandleErrorAttribute());
        filters.Add(new AuthorizeAttribute());
    }
  3. สร้างหน้าข้อผิดพลาดที่กำหนดเองสำหรับแต่ละข้อความด้านบน ค่าเริ่มต้นสำหรับ 500 นั้นมีอยู่แล้วในกล่อง

  4. ประกาศในแต่ละหน้ามุมมองข้อผิดพลาดที่กำหนดเองว่ารูปแบบของหน้านั้นคืออะไร System.Web.Mvc.HandleErrorInfo

สำหรับ 500 จะแสดงหน้าข้อผิดพลาดที่กำหนดเอง สำหรับคนอื่นมันไม่ได้

มีบางอย่างที่ฉันขาดหายไปหรือไม่?

มันดูเหมือนว่านี่ไม่ใช่ทั้งหมดที่มีเพื่อแสดงข้อผิดพลาดที่กำหนดเองเมื่อฉันอ่านรหัสในOnExceptionวิธีการHandleErrorAttributeเรียนและมันจัดการเพียง 500

ฉันต้องทำอย่างไรเพื่อจัดการข้อผิดพลาดอื่น ๆ


21
สิ่งที่แปลกสำหรับการตั้งค่านี้คือการเปลี่ยนเส้นทางไปยังมุมมองไม่ใช่การกระทำของตัวควบคุม ใครควรแสดงมุมมองเหล่านั้นและส่งผ่านตัวอย่าง แค่คิด
Oliver

2
คำตอบส่วนใหญ่ที่นี่ไม่ได้จัดการทุกกรณีหรือทำให้เว็บเซิร์ฟเวอร์ตอบกลับด้วยวิธี "ไม่ถูกต้อง" นั่นคือเปลี่ยนเส้นทางไปยังหน้าแสดงข้อผิดพลาดแทนที่จะส่งคืนการตอบกลับข้อผิดพลาด หากคุณสนใจเกี่ยวกับเซิร์ฟเวอร์การตอบสนองในทางที่คาดหวังของเว็บเซิร์ฟเวอร์นั้นมีค่อนข้างบทความรายละเอียดเกี่ยวกับที่นี่: benfoster.io/blog/aspnet-mvc-custom-error-pages ถูกเตือนว่ามันไม่ตรงไปตรงมาเหมือนคำตอบที่นี่ดังนั้นหากคุณต้องการคำตอบง่ายๆให้ใช้คำใดคำหนึ่งด้านล่างแทน
rdans

1
นี่เป็นอีกบทความที่ดีเกี่ยวกับเทคนิคต่าง ๆ สำหรับการจัดการข้อผิดพลาด asp.net dusted.codes/ …
Godsayah

คำตอบ:


352

การตั้งค่าปัจจุบันของฉัน (ใน MVC3 แต่ฉันคิดว่ามันยังใช้งานได้) ขึ้นอยู่กับการมีErrorControllerดังนั้นฉันใช้:

<system.web>
    <customErrors mode="On" defaultRedirect="~/Error">
      <error redirect="~/Error/NotFound" statusCode="404" />
    </customErrors>
</system.web>

และตัวควบคุมประกอบด้วยสิ่งต่อไปนี้:

public class ErrorController : Controller
{
    public ViewResult Index()
    {
        return View("Error");
    }
    public ViewResult NotFound()
    {
        Response.StatusCode = 404;  //you may want to set this to 200
        return View("NotFound");
    }
}

และมุมมองในแบบที่คุณใช้ ฉันมักจะเพิ่มตรรกะเล็กน้อยเพื่อแสดง stack trace และข้อมูลข้อผิดพลาดหากแอปพลิเคชันอยู่ในโหมด debug ดังนั้น Error.cshtml จึงมีลักษณะดังนี้:

@model System.Web.Mvc.HandleErrorInfo
@{
    Layout = "_Layout.cshtml";
    ViewBag.Title = "Error";
}
<div class="list-header clearfix">
    <span>Error</span>
</div>
<div class="list-sfs-holder">
    <div class="alert alert-error">
        An unexpected error has occurred. Please contact the system administrator.
    </div>
    @if (Model != null && HttpContext.Current.IsDebuggingEnabled)
    {
        <div>
            <p>
                <b>Exception:</b> @Model.Exception.Message<br />
                <b>Controller:</b> @Model.ControllerName<br />
                <b>Action:</b> @Model.ActionName
            </p>
            <div style="overflow:scroll">
                <pre>
                    @Model.Exception.StackTrace
                </pre>
            </div>
        </div>
    }
</div>

7
คุณต้องใส่อะไรใน Application_Error ใน Global.asax ของคุณสำหรับ Pablo นี้หรือไม่?
อลิเซีย

12
ดูเหมือนว่ารหัสในคอนโทรลเลอร์จะไม่ทำงานจากประสบการณ์ของฉัน MVC4 - การโยน System.Exception ในคอนโทรลเลอร์อื่นจะทำให้ไฟล์ Error.cshtml แสดงผล แต่ไม่ผ่าน ErrorController ใครบ้างที่ประสบปัญหานี้
Nilzor

53
สำหรับคนอื่นที่เห็นว่ามีประโยชน์ แต่ต้องการบริบทมากกว่านี้ แท็ก <customErrors> อยู่ใน <system.web> ใน web.config
gooberverse

7
อัปเดตสำหรับคนอื่น ๆ - เห็นได้ชัดว่าปัญหาของฉันที่เกิดขึ้นเพราะผมมีredirectMode="ResponseRewrite"ในCustomerErrorsองค์ประกอบ
KyleMit

42
กรุณาสำหรับความรักของพระเจ้าไม่สนใจความคิดเห็นพูด//you may want to set this to 200ในรหัส อย่าทำอย่างนั้น!
Dementic

40

ฉันทำโซลูชัน pablo เสร็จแล้วและมักมีข้อผิดพลาด (MVC4)

ไม่พบมุมมอง 'ข้อผิดพลาด' หรือต้นแบบของเครื่องมือนั้นหรือไม่มีเครื่องมือมุมมองรองรับตำแหน่งที่ค้นหา

หากต้องการกำจัดสิ่งนี้ให้ลบบรรทัดออก

 filters.Add(new HandleErrorAttribute());

ใน FilterConfig.cs


ฉันมองไปทุกที่เพื่อแก้ไขปัญหานี้ ในที่สุดก็มีคำตอบ ฉันรู้ว่าทำไมมันถึงทำได้ แต่สำหรับฉันแล้วฉันก็ทำไม่ได้โดยไม่ได้คิดอะไรอย่างที่คนอื่นพูด ฉันจินตนาการว่าฉันแบ่งปันความเจ็บปวดของ 360Airwalk เมื่อฉันบอกว่าขอบคุณที่ชี้ให้เห็น ตำนาน!
อดัม

นี่คือหนึ่งในตัวเลือกและตัวควบคุมข้อผิดพลาดทำงานได้ดี แต่ดูเหมือนว่าเมื่อคุณลงทะเบียนตัวกรองใน FilterConfig.cs จะมองหา Error.cshtml ในโฟลเดอร์มุมมองของตัวควบคุมที่แชร์และตัวควบคุมดั้งเดิม เมื่อคุณเปลี่ยน Error.cshtml ไปเป็นสิ่งอื่นนอกเหนือจาก ErrorController ที่กำหนดเองของเราจะทำงาน แต่มีสถานที่ที่คุณสามารถเพิ่มการลงทะเบียนนี้และเป็น global.asax.cs หากคุณเพิ่มบรรทัดที่กล่าวถึงในฟังก์ชัน RegisterGlobalFilters (ตัวกรอง GlobalFilterCollection) ใน global.asax.cs และลบออกจาก FilterConfig.cs จะทำงาน
isaolmez

ฉันคิดว่าเกี่ยวข้องกับคำสั่งของการลงทะเบียนตัวกรอง รักษาตัวควบคุมข้อผิดพลาดและย้ายการลงทะเบียนตัวกรองไปยัง global.asax.cs โมฆะคงที่สาธารณะ RegisterGlobalFilters (ตัวกรอง GlobalFilterCollection) {ตัวกรองเพิ่ม (ใหม่ HandleErrorAttribute ()); }
isaolmez

24

ฉันทำบางสิ่งที่ต้องการการเข้ารหัสน้อยกว่าโซลูชันอื่น ๆ ที่โพสต์

ก่อนอื่นใน web.config ของฉันฉันมีดังต่อไปนี้:

<customErrors mode="On" defaultRedirect="~/ErrorPage/Oops">
   <error redirect="~/ErrorPage/Oops/404" statusCode="404" />
   <error redirect="~/ErrorPage/Oops/500" statusCode="500" />
</customErrors>

และคอนโทรลเลอร์ (/Controllers/ErrorPageController.cs) มีสิ่งต่อไปนี้:

public class ErrorPageController : Controller
{
    public ActionResult Oops(int id)
    {
        Response.StatusCode = id;

        return View();
    }
}

และในที่สุดมุมมองมีสิ่งต่อไปนี้ (ถอดออกเพื่อความเรียบง่าย แต่มันสามารถต่อ:

@{ ViewBag.Title = "Oops! Error Encountered"; }

<section id="Page">
  <div class="col-xs-12 well">
    <table cellspacing="5" cellpadding="3" style="background-color:#fff;width:100%;" class="table-responsive">
      <tbody>
        <tr>
          <td valign="top" align="left" id="tableProps">
            <img width="25" height="33" src="~/Images/PageError.gif" id="pagerrorImg">
          </td>
          <td width="360" valign="middle" align="left" id="tableProps2">
            <h1 style="COLOR: black; FONT: 13pt/15pt verdana" id="errortype"><span id="errorText">@Response.Status</span></h1>
          </td>
        </tr>
        <tr>
          <td width="400" colspan="2" id="tablePropsWidth"><font style="COLOR: black; FONT: 8pt/11pt verdana">Possible causes:</font>
          </td>
        </tr>
        <tr>
          <td width="400" colspan="2" id="tablePropsWidth2">
            <font style="COLOR: black; FONT: 8pt/11pt verdana" id="LID1">
                            <hr>
                            <ul>
                                <li id="list1">
                                    <span class="infotext">
                                        <strong>Baptist explanation: </strong>There
                                        must be sin in your life. Everyone else opened it fine.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Presbyterian explanation: </strong>It's
                                        not God's will for you to open this link.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong> Word of Faith explanation:</strong>
                                        You lack the faith to open this link. Your negative words have prevented
                                        you from realizing this link's fulfillment.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Charismatic explanation: </strong>Thou
                                        art loosed! Be commanded to OPEN!<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Unitarian explanation:</strong> All
                                        links are equal, so if this link doesn't work for you, feel free to
                                        experiment with other links that might bring you joy and fulfillment.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Buddhist explanation:</strong> .........................<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Episcopalian explanation:</strong>
                                        Are you saying you have something against homosexuals?<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Christian Science explanation: </strong>There
                                        really is no link.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Atheist explanation: </strong>The only
                                        reason you think this link exists is because you needed to invent it.<br>
                                    </span>
                                </li>
                                <li>
                                    <span class="infotext">
                                        <strong>Church counselor's explanation:</strong>
                                        And what did you feel when the link would not open?
                                    </span>
                                </li>
                            </ul>
                            <p>
                                <br>
                            </p>
                            <h2 style="font:8pt/11pt verdana; color:black" id="ietext">
                                <img width="16" height="16" align="top" src="~/Images/Search.gif">
                                HTTP @Response.StatusCode - @Response.StatusDescription <br>
                            </h2>
                        </font>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</section>

มันง่ายอย่างที่คิด มันสามารถขยายออกได้อย่างง่ายดายเพื่อให้ข้อมูลข้อผิดพลาดโดยละเอียดมากขึ้น แต่ELMAHจัดการกับฉัน & the statusCode & statusDescription เป็นสิ่งที่ฉันต้องการ


ฉันคิดว่าการเปลี่ยนเส้นทางในไฟล์. config ของ "~ / ErrorPage / Oops / 404" น่าจะเป็น "~ / ErrorPage / Oops? 404" ใช่ไหม อย่างน้อยนั่นเป็นสิ่งที่ใช้ได้ผลสำหรับฉัน บางทีนั่นอาจขึ้นอยู่กับการกำหนดเส้นทาง
Josh Sutterfield

วิธีจำลองข้อผิดพลาดที่เกิดจาก IIS ไม่ว่าจะเป็น 500 หรือ 504 สิ่งที่ต้องทำใน ASP.Net MVC - 5 รหัสเพื่อจำลองข้อยกเว้นจาก IIS เพื่อให้ฉันสามารถทดสอบหน้าข้อผิดพลาดที่กำหนดเองของฉัน
Unbreakable

12

ดูเหมือนจะมีหลายขั้นตอนในการทำงานร่วมกัน ฉันจะหยิบยกสิ่งที่ฉันทำตั้งแต่เริ่มต้น

  1. สร้างErrorPageตัวควบคุม

    public class ErrorPageController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        public ActionResult Oops(int id)
        {
            Response.StatusCode = id;
            return View();
        }
    }
  2. เพิ่มมุมมองสำหรับการกระทำสองอย่างนี้ (คลิกขวา -> เพิ่มมุมมอง) สิ่งเหล่านี้ควรปรากฏในโฟลเดอร์ที่ชื่อว่า ErrorPage

  3. ข้างในApp_Startเปิดขึ้นFilterConfig.csและแสดงความคิดเห็นออกตัวจัดการข้อผิดพลาด

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        // Remove this filter because we want to handle errors ourselves via the ErrorPage controller
        //filters.Add(new HandleErrorAttribute());
    }
  4. ภายใน web.config เพิ่ม<customerErrors>รายการต่อไปนี้ภายใต้System.Web

    <customErrors mode="On" defaultRedirect="~/ErrorPage/Oops">
        <error redirect="~/ErrorPage/Oops/404" statusCode="404" />
        <error redirect="~/ErrorPage/Oops/500" statusCode="500" />
    </customErrors>
  5. ทดสอบ (แน่นอน) ส่งข้อยกเว้นที่ไม่สามารถจัดการได้ในรหัสของคุณแล้วดูไปที่หน้าที่มี id 500 จากนั้นใช้ URL ไปยังหน้าเว็บที่ไม่มีอยู่เพื่อดู 404


ฉันได้รับข้อผิดพลาดAn exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.ทั้งหมดที่ฉันหยิบขึ้นมาจากรหัสของคุณอยู่ในไฟล์ web.config ฉันเพิ่ม<error redirect = "~/ControllerName/ActionName" statusCode="404"/>และใช้งานได้ดี :) ส่วนที่เหลือของรหัสนั้นมาจากคำตอบของ @ Pablo ฉันกำลังใช้ MVC 5 และเฟรมเวิร์กเอนทิตี 6 ฉันไม่ได้ลบออกfilters.Add(new HandleErrorAttribute())จากFilterConfig.cs
sumedha

วิธีจำลองข้อผิดพลาดที่เกิดจาก IIS ไม่ว่าจะเป็น 500 หรือ 504 สิ่งที่ต้องทำใน ASP.Net MVC - 5 รหัสเพื่อจำลองข้อยกเว้นจาก IIS เพื่อให้ฉันสามารถทดสอบหน้าข้อผิดพลาดที่กำหนดเองของฉัน
Unbreakable

นอกจากนี้วิธีการโยนข้อยกเว้นที่ไม่สามารถจัดการได้ (ขั้นตอนที่ 5) ฉันใหม่เพื่อการเข้ารหัสโปรดแนะนำ
ไม่สามารถแตกได้

ยังไม่ได้ผลสำหรับฉัน แล้วเส้นทางล่ะ ฉันต้องเพิ่มการกำหนดเส้นทางสำหรับหน้าข้อผิดพลาดด้วยหรือไม่ ถ้าฉันกด page: localhost: 84 / Enforcer / blahฉันถูกเปลี่ยนเส้นทางไปที่: localhost: 84 / Enforcer / Enforcer / Error / NotFound? aspxerrorpath = / …หน้าแสดงข้อผิดพลาดดูเหมือนหน้าข้อผิดพลาดมาตรฐานที่ได้รับจาก Asp.NET ความคิดใด ๆ
Radek Strugalski

องค์ประกอบ customerrors ใน webconfig ควรจะทำสิ่งนี้ รหัสเส้นทางเริ่มต้น (สร้างโครงการ) ของคุณควรทำงานได้ดี
VictorySaber

11

ฉันอยากจะแนะนำให้ใช้ไฟล์ Global.asax.cs

 protected void Application_Error(Object sender, EventArgs e)
{
    var exception = Server.GetLastError();
    if (exception is HttpUnhandledException)
    {
        Server.Transfer("~/Error.aspx");
    }
    if (exception != null)
    {
        Server.Transfer("~/Error.aspx");
    }
    try
    {
        // This is to stop a problem where we were seeing "gibberish" in the
        // chrome and firefox browsers
        HttpApplication app = sender as HttpApplication;
        app.Response.Filter = null;
    }
    catch
    {
    }
}

1
ฉันไม่คิดว่าคุณสามารถทำ Server.Transfer () ใน MVC ได้ คุณคิดว่า OP มีไซต์ที่หลากหลายหรือไม่
แร็พ

1
ทำไมเราควรใช้ Application_Error ใน mvc เรามีตัวเลือกเช่น [handleerror] ที่มาพร้อมกับตัวเลือก URL การเปลี่ยนเส้นทาง มีข้อได้เปรียบเฉพาะกับ application_error หรือไม่?
Kurkula

เราควรใช้ HandleErrorAttribute ใน MVC และโดยแทนที่วิธี OnException เราสามารถจัดการกับมันได้ดีกว่ามาก
Kumar Lachhani

7

จากคำตอบที่โพสต์โดย maxspan ฉันได้รวบรวมตัวอย่างโครงการขั้นต่ำไว้ที่ GitHubซึ่งแสดงชิ้นส่วนที่ทำงานทั้งหมด

โดยทั่วไปเราเพิ่งเพิ่มApplication_Errorวิธีการ global.asax.csเพื่อสกัดกั้นข้อยกเว้นและให้โอกาสเราในการเปลี่ยนเส้นทาง (หรืออย่างถูกต้องมากขึ้นโอนคำขอ ) ไปยังหน้าข้อผิดพลาดที่กำหนดเอง

    protected void Application_Error(Object sender, EventArgs e)
    {
        // See http://stackoverflow.com/questions/13905164/how-to-make-custom-error-pages-work-in-asp-net-mvc-4
        // for additional context on use of this technique

        var exception = Server.GetLastError();
        if (exception != null)
        {
            // This would be a good place to log any relevant details about the exception.
            // Since we are going to pass exception information to our error page via querystring,
            // it will only be practical to issue a short message. Further detail would have to be logged somewhere.

            // This will invoke our error page, passing the exception message via querystring parameter
            // Note that we chose to use Server.TransferRequest, which is only supported in IIS 7 and above.
            // As an alternative, Response.Redirect could be used instead.
            // Server.Transfer does not work (see https://support.microsoft.com/en-us/kb/320439 )
            Server.TransferRequest("~/Error?Message=" + exception.Message);
        }

    }

ตัวควบคุมข้อผิดพลาด:

/// <summary>
/// This controller exists to provide the error page
/// </summary>
public class ErrorController : Controller
{
    /// <summary>
    /// This action represents the error page
    /// </summary>
    /// <param name="Message">Error message to be displayed (provided via querystring parameter - a design choice)</param>
    /// <returns></returns>
    public ActionResult Index(string Message)
    {
        // We choose to use the ViewBag to communicate the error message to the view
        ViewBag.Message = Message;
        return View();
    }

}

มุมมองหน้าข้อผิดพลาด:

<!DOCTYPE html>

<html>
<head>
    <title>Error</title>
</head>
<body>

    <h2>My Error</h2>
    <p>@ViewBag.Message</p>
</body>
</html>

ไม่มีสิ่งใดเกี่ยวข้องเกี่ยวข้องนอกเหนือจากการปิดใช้งาน / ลบfilters.Add(new HandleErrorAttribute())ในFilterConfig.cs

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        //filters.Add(new HandleErrorAttribute()); // <== disable/remove
    }
}

ในขณะที่ใช้งานได้ง่ายข้อเสียเปรียบอย่างหนึ่งที่ฉันเห็นในวิธีนี้คือการใช้การสอบถามเพื่อส่งข้อมูลข้อยกเว้นไปยังหน้าข้อผิดพลาดเป้าหมาย


3

ฉันตั้งค่าทุกอย่างแล้ว แต่ก็ยังไม่เห็นหน้าข้อผิดพลาดที่เหมาะสมสำหรับรหัสสถานะ 500 บนเซิร์ฟเวอร์ทดสอบของเราแม้ว่าทุกอย่างทำงานได้ดีบนเซิร์ฟเวอร์พัฒนาท้องถิ่น

ฉันพบโพสต์บล็อกนี้จาก Rick Strahl ที่ช่วยฉัน

ฉันต้องการเพิ่มResponse.TrySkipIisCustomErrors = true;รหัสการจัดการข้อผิดพลาดที่กำหนดเองของฉัน


@ Shaun314 คุณหมายถึงที่ไหนคุณใส่รหัสที่? ในการกระทำที่จัดการคำขอ คุณสามารถดูตัวอย่างในโพสต์บล็อกนั้น
DCShannon

2

นี่คือทางออกของฉัน ใช้[ExportModelStateToTempData] / [ImportModelStateFromTempData]ไม่สะดวกในความคิดของฉัน

~ / อ่าน / Home / Error.cshtml:

@{
    ViewBag.Title = "Error";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Error</h2>
<hr/>

<div style="min-height: 400px;">

    @Html.ValidationMessage("Error")

    <br />
    <br />

    <button onclick="Error_goBack()" class="k-button">Go Back</button>
    <script>
        function Error_goBack() {
            window.history.back()
        }
    </script>

</div>

~ / ควบคุม / HomeController.sc:

public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Error()
    {
        return this.View();
    }

    ...
}

~ / ควบคุม / BaseController.sc:

public class BaseController : Controller
{
    public BaseController() { }

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Result is ViewResult)
        {
            if (filterContext.Controller.TempData.ContainsKey("Error"))
            {
                var modelState = filterContext.Controller.TempData["Error"] as ModelState;
                filterContext.Controller.ViewData.ModelState.Merge(new ModelStateDictionary() { new KeyValuePair<string, ModelState>("Error", modelState) });
                filterContext.Controller.TempData.Remove("Error");
            }
        }
        if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
        {
            if (filterContext.Controller.ViewData.ModelState.ContainsKey("Error"))
            {
                filterContext.Controller.TempData["Error"] = filterContext.Controller.ViewData.ModelState["Error"];
            }
        }

        base.OnActionExecuted(filterContext);
    }
}

~ / ควบคุม / MyController.sc:

public class MyController : BaseController
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Details(int id)
    {
        if (id != 5)
        {
            ModelState.AddModelError("Error", "Specified row does not exist.");
            return RedirectToAction("Error", "Home");
        }
        else
        {
            return View("Specified row exists.");
        }
    }
}

ฉันขอให้คุณโครงการที่ประสบความสำเร็จ ;-)


2

คุณสามารถรับข้อผิดพลาดในการทำงานอย่างถูกต้องโดยไม่ต้องแฮ็ก global.cs, messing กับ HandleErrorAttribute, ทำ Response.TrySkipIisCustomErrors, hooking Application_Error หรืออะไรก็ตาม:

ใน system.web (ปกติเปิด / ปิด)

<customErrors mode="On">
  <error redirect="/error/401" statusCode="401" />
  <error redirect="/error/500" statusCode="500" />
</customErrors>

และใน system.webServer

<httpErrors existingResponse="PassThrough" />

ตอนนี้สิ่งต่าง ๆ ควรทำงานได้ตามที่คาดไว้และคุณสามารถใช้ ErrorController เพื่อแสดงสิ่งที่คุณต้องการ


วิธีจำลองข้อผิดพลาดที่เกิดจาก IIS ไม่ว่าจะเป็น 500 หรือ 504 สิ่งที่ต้องทำใน ASP.Net MVC - 5 รหัสเพื่อจำลองข้อยกเว้นจาก IIS เพื่อให้ฉันสามารถทดสอบหน้าข้อผิดพลาดที่กำหนดเองของฉัน
Unbreakable

@ Unbreakable เปลี่ยนรหัสของคุณเป็นการชั่วคราวเพื่อยกเว้น
พวกเขาเรียกเก็บเงินจาก

ไม่ได้สร้างความแตกต่างให้ฉัน ฉันไม่ได้ถูกนำไปยังหน้าข้อผิดพลาดที่กำหนดเองตามข้อยกเว้นหรือ 404 ไม่พบข้อผิดพลาด
pnizzle

0

ดูเหมือนว่าฉันจะมาสายไปงานเลี้ยง แต่คุณควรตรวจสอบเรื่องนี้ด้วย

ดังนั้นในsystem.webการแคชข้อยกเว้นภายในแอปพลิเคชันเช่น return HttpNotFound ()

  <system.web>
    <customErrors mode="RemoteOnly">
      <error statusCode="404" redirect="/page-not-found" />
      <error statusCode="500" redirect="/internal-server-error" />
    </customErrors>
  </system.web>

และในsystem.webServerการติดตามข้อผิดพลาดที่ IIS จับได้และไม่ได้ดำเนินการตามกรอบ asp.net

 <system.webServer>
    <httpErrors errorMode="DetailedLocalOnly">
      <remove statusCode="404"/>
      <error statusCode="404" path="/page-not-found" responseMode="Redirect"/>
      <remove statusCode="500"/>
      <error statusCode="500" path="/internal-server-error" responseMode="Redirect"/>
  </system.webServer>

ในช่วงหนึ่งถ้าคุณกังวลเกี่ยวกับการตอบสนองลูกค้าแล้วเปลี่ยนresponseMode="Redirect"ไปresponseMode="File"และให้บริการไฟล์คง HTML, ตั้งแต่หนึ่งนี้จะแสดงหน้าเป็นมิตรกับรหัส 200 การตอบสนอง


0

ใน web.config เพิ่มสิ่งนี้ภายใต้แท็ก system.webserver ดังต่อไปนี้

<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="404"/>
  <remove statusCode="500"/>
  <error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound"/>
  <error statusCode="500" responseMode="ExecuteURL"path="/Error/ErrorPage"/>
</httpErrors>

และเพิ่มตัวควบคุมเป็น

public class ErrorController : Controller
{
    //
    // GET: /Error/
    [GET("/Error/NotFound")]
    public ActionResult NotFound()
    {
        Response.StatusCode = 404;

        return View();
    }

    [GET("/Error/ErrorPage")]
    public ActionResult ErrorPage()
    {
        Response.StatusCode = 500;

        return View();
    }
}

และเพิ่มมุมมองที่เคารพของพวกเขาสิ่งนี้จะใช้ได้แน่นอนฉันเดาได้ทั้งหมด

วิธีนี้ฉันพบจาก: เนปจูนเซ็นจูรี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.