[asp.net] ASP.NET MVC 4에서 사용자 지정 오류 페이지를 작동시키는 방법

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메소드 에서 코드를 읽을 때 사용자 정의 오류가 표시되는 것은 아니며 HandleErrorAttribute500 개만 처리하는 것 같습니다.

다른 오류를 처리하려면 어떻게해야합니까?



답변

내 현재 설정 (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");
    }
}

뷰는 구현 방식과 동일합니다. 그래도 응용 프로그램이 디버그 모드에있는 경우 스택 추적 및 오류 정보를 표시하기 위해 약간의 논리를 추가하는 경향이 있습니다. 따라서 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>


답변

파블로 솔루션을 수행했으며 항상 오류가 발생했습니다 (MVC4)

‘오류’보기 또는 해당 마스터를 찾을 수 없거나 검색된 위치를 지원하는보기 엔진이 없습니다.

이를 제거하려면 줄을 제거하십시오

 filters.Add(new HandleErrorAttribute());

FilterConfig.cs에서


답변

게시 된 다른 솔루션보다 코딩이 덜 필요한 작업을 수행합니다.

먼저 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 는 나를 위해 처리하며 statusCode 및 statusDescription 만 있으면됩니다.


답변

여기에 여러 단계가 뒤섞인 것 같습니다. 내가 한 일을 처음부터 전달하겠습니다.

  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를 확인하십시오.


답변

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
    {
    }
}


답변

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>

FilterConfig.csfilters.Add(new HandleErrorAttribute()) 에서 비활성화 / 제거 이외의 다른 것은 없습니다

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

구현이 매우 간단하지만이 방법에서 볼 수있는 한 가지 단점은 querystring을 사용하여 예외 정보를 대상 오류 페이지에 전달하는 것입니다.


답변

모든 것이 설정되었지만 로컬 개발 서버에서 모든 것이 제대로 작동했지만 스테이징 서버에서 상태 코드 500에 대한 적절한 오류 페이지를 여전히 볼 수 없었습니다.

나는 발견 이 블로그 게시물 나를 도와 릭 Strahl에서합니다.

Response.TrySkipIisCustomErrors = true;사용자 지정 오류 처리 코드 를 추가해야했습니다 .