사용자 지정 ASP.NET MVC 404 오류 페이지에 대한 라우팅


116

일반 "Resource Not Found"ASP.NET 오류를 표시하는 대신 ASP.NET MVC에서 유효한 동작이나 컨트롤러를 호출하지 않는 URL을 입력 할 때 사용자 지정 HTTP 404 오류 페이지를 만들려고합니다.

나는 이것을 처리하기 위해 web.config를 사용하고 싶지 않습니다.

잘못된 URL을 포착하기 위해 할 수있는 라우팅 마법이 있습니까?

업데이트 : 주어진 대답을 시도했지만 여전히 추악한 "Resource Not Found"메시지가 나타납니다.

또 다른 업데이트 : RC1에서 뭔가 변경된 것 같습니다 . 나는 특별히 404 트랩을 시도했지만 HttpException여전히 "Resource Not Found"페이지 만 표시됩니다.

MvcContrib의 리소스 기능도 사용했지만 동일한 문제가 없습니다. 어떤 아이디어?



@Peter 이것은 HandleUnknownAction을 재정 의하여 작업이 존재하지 않을 때 페이지를 찾을 수 없음보기를 표시 한 다음 내장 된 ASP.net 사용자 지정 오류 처리기를 통해 사용자가 입력 할 수있는 다른 문제를 처리하는 솔루션입니다. .
dswatik

뿐만 아니라이 작품을 @pete stackoverflow.com/questions/619895/...
dswatik

8
다른 사용자가 주제 넘어 "왜 그렇게하고 싶니? 그냥하세요 ..."와 같은 말을하는 게 싫어요.하지만 web.config 접근 방식을 사용하는 것을 막을 수 없다면 귀하의 요구를 충족시키는 표준적이고 우아한 접근 방식입니다. 그 접근 방식에 대한 모든 피드백은 제가 알지 못하는 문제가있을 수 있기 때문에 감사합니다.
Sean

답변:


10

경로 테이블 끝에 모든 경로를 추가하고 원하는 페이지를 표시하십시오.

참조 : ASP.NET MVC에 대한 '404 페이지를 찾을 수 없음'쿼리를 처리하기 위해 모든 경로를 catch하려면 어떻게해야합니까?


그러나 나는 이것을 시도했지만 여전히 못생긴 ASP.NET 기본 리소스를 찾을 수 없음 메시지가 나타납니다.
dswatik

3
이 답변이나 제공된 링크 에서이 문제에 대한 확실한 (그리고 유연한 !!) 해결책을 찾지 못했습니다.
Peter

4
나도 ... 이건 일종의 해키 대답처럼 보입니다. customErrors가 WebForms에서와 같이 동작하도록 만드는 방법을 더 찾고 있습니다. 어떤 아이디어?
JC Grubbs

1
이것은 둘 다 작동하지 않으며 원칙적으로 나쁩니다. 이전 경로 패턴 중 하나와 일치하는 잘못된 URL을 포착하지 않기 때문에 작동하지 않습니다. 원칙에 나쁜 그것은 무엇 변환하기 때문에 해야 하지 오류에 대한 오류합니다. 이름이 "오류"인 페이지로 리디렉션하는 것은 오류 페이지로 리디렉션하는 것과 다릅니다. 오류로 유지하고 오류를 기록한 다음 오류로 처리하려고합니다. 오류는 중요한 정보입니다.
Matthew

105

3 시간 동안 프로덕션 서버에서 사용자 지정 오류를 활성화하려고 시도했지만 경로없이 ASP.NET MVC에서이를 수행하는 방법에 대한 최종 솔루션을 찾은 것 같습니다.

ASP.NET MVC 응용 프로그램에서 사용자 지정 오류를 사용하려면 다음이 필요합니다 (IIS 7 이상).

  1. system.web섹션 아래의 웹 구성에서 사용자 정의 페이지를 구성 하십시오.

    <customErrors mode="RemoteOnly"  defaultRedirect="~/error">
        <error statusCode="404" redirect="~/error/Error404" />
        <error statusCode="500" redirect="~/error" />
    </customErrors>

    RemoteOnly즉, 로컬 네트워크에서 실제 오류가 표시됩니다 (개발 중에 매우 유용함). 오류 코드에 대한 오류 페이지를 다시 작성할 수도 있습니다.

  2. 매직 응답 매개 변수 및 응답 상태 코드 설정 (오류 처리 모듈 또는 오류 처리 속성)

      HttpContext.Current.Response.StatusCode = 500;
      HttpContext.Current.Response.TrySkipIisCustomErrors = true;
  3. system.webServer섹션 아래의 웹 구성에서 다른 매직 설정을 설정 하십시오.

    <httpErrors errorMode="Detailed" />

이것은 내가 찾은 마지막 것이었고 그 후에 프로덕션 서버에서 사용자 정의 오류를 볼 수 있습니다.


8
이것은 여전히 ​​이상적인 솔루션이 아닙니다. 적절한 HTTP 응답 코드를 얻지 못합니다. customErrors결과를 사용하면 오류 페이지를로드하기 위해 302 리디렉션이 발생합니다.
Justin Helgerson 2014

Ek0nomik @ 나는 이상적인 솔루션을 :) 본 적이
앤드류 Orsich

2
@JustinHelgerson 각 상태 코드에 대해 ErrorController를 설정하고 해당 작업 내에 응답 코드를 설정하고 응답 코드를 잘 설정합니다. Fiddler로 테스트하고 404 상태 코드가 404로 응답하고 500 개 오류가있는 페이지가 500으로 응답합니다. 그리고 두 경우 모두 내 사용자 지정 오류보기가 제공됩니다
Shane Neuville

내 팀 동료가 바로 오류보기를 삭제 에서 공유 된 폴더, 500 상태 코드와 런타임 오류를 만들려면 사용자 지정 오류 페이지로 리디렉션 언급 한 바와 같이 여기여기 . 희망은 누군가를 돕습니다.
shaijut

41

이 기사의 뷰를 반환하는 ErrorController를 만들어 오류 처리가 작동하도록했습니다. 또한 global.asax의 경로에 "Catch All"을 추가해야했습니다.

Web.config에없는 경우 이러한 오류 페이지가 어떻게 표시되는지 볼 수 없습니다 ..? 내 Web.config는 다음을 지정해야했습니다.

customErrors mode="On" defaultRedirect="~/Error/Unknown"

그리고 다음을 추가했습니다.

error statusCode="404" redirect="~/Error/NotFound"

2
감사합니다. 2 년 후 도움이되었습니다! 404에 대한 사용자 지정 오류 만 원하는 경우에는 어떻게합니까?
Shaul Behr

1
1 년 후 @Shaul ... defaultRedirect를 설정하지 말고 속성을 모두 제외하십시오.
NJE

27

출처

NotFoundMVC 컨트롤러, 작업 또는 경로가 ASP.NET MVC3 응용 프로그램에서 발견되지 않을 때마다 사용자 친화적 인 404 페이지를 제공합니다. 기본 ASP.NET 오류 페이지 대신 NotFound라는 뷰가 렌더링됩니다.

다음을 사용하여 nuget을 통해이 플러그인을 추가 할 수 있습니다. Install-Package NotFoundMvc

NotFoundMvc는 웹 응용 프로그램을 시작하는 동안 자동으로 설치됩니다. 일반적으로 ASP.NET MVC에서 404 HttpException이 발생하는 모든 다른 방식을 처리합니다. 여기에는 누락 된 컨트롤러, 작업 및 경로가 포함됩니다.

단계별 설치 가이드 :

1-프로젝트를 마우스 오른쪽 버튼으로 클릭하고 Nuget 패키지 관리 ...를 선택합니다.

2-검색하여 NotFoundMvc설치합니다. 여기에 이미지 설명 입력

3-설치가 완료되면 두 개의 파일이 프로젝트에 추가됩니다. 아래 스크린 샷과 같습니다.

여기에 이미지 설명 입력

4-Views / Shared에 새로 추가 된 NotFound.cshtml을 열고 원하는대로 수정합니다. 이제 응용 프로그램을 실행하고 잘못된 URL을 입력하면 사용자 친화적 인 404 페이지가 표시됩니다.

여기에 이미지 설명 입력

더 이상 사용자는 다음과 같은 오류 메시지를 받게됩니다. Server Error in '/' Application. The resource cannot be found.

도움이 되었기를 바랍니다 :)

추신 : 멋진 플러그인을 만든 Andrew Davey 에게 찬사를 보냅니다 .


@niico 소스 코드를 보면 응답 코드를 404로 설정 한 것처럼 보이므로 그렇습니다.
Will Dean

20

web.config에서 이것을 시도하여 IIS 오류 페이지를 교체하십시오. 이것은 내가 생각하는 최고의 솔루션이며 올바른 상태 코드도 보냅니다.

<system.webServer>
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" subStatusCode="-1" />
    <remove statusCode="500" subStatusCode="-1" />
    <error statusCode="404" path="Error404.html" responseMode="File" />
    <error statusCode="500" path="Error.html" responseMode="File" />
  </httpErrors>
</system.webServer>

Tipila의 추가 정보 -사용자 지정 오류 페이지 사용 ASP.NET MVC


1
+1. 이것은 여러 영역을 가진 MVC5에서 나에게 일관되게 작동하는 유일한 것입니다.
hawkke 2014

이것이 가장 쉬운 해결책입니다. 그래도 오류 페이지에서 razor 구문을 사용할 수 없습니다.
highace

15

이 솔루션은 web.config 파일 변경이나 포괄 경로가 필요하지 않습니다.

먼저 다음과 같은 컨트롤러를 만듭니다.

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Title = "Regular Error";
        return View();
    }

    public ActionResult NotFound404()
    {
        ViewBag.Title = "Error 404 - File not Found";
        return View("Index");
    }
}

그런 다음 "Views / Error / Index.cshtml"아래에보기를 다음과 같이 만듭니다.

 @{
      Layout = "~/Views/Shared/_Layout.cshtml";
  }                     
  <p>We're sorry, page you're looking for is, sadly, not here.</p>

그런 다음 아래와 같이 Global asax 파일에 다음을 추가하십시오.

protected void Application_Error(object sender, EventArgs e)
{
        // Do whatever you want to do with the error

        //Show the custom error page...
        Server.ClearError(); 
        var routeData = new RouteData();
        routeData.Values["controller"] = "Error";

        if ((Context.Server.GetLastError() is HttpException) && ((Context.Server.GetLastError() as HttpException).GetHttpCode() != 404))
        {
            routeData.Values["action"] = "Index";
        }
        else
        {
            // Handle 404 error and response code
            Response.StatusCode = 404;
            routeData.Values["action"] = "NotFound404";
        } 
        Response.TrySkipIisCustomErrors = true; // If you are using IIS7, have this line
        IController errorsController = new ErrorController();
        HttpContextWrapper wrapper = new HttpContextWrapper(Context);
        var rc = new System.Web.Routing.RequestContext(wrapper, routeData);
        errorsController.Execute(rc);

        Response.End();
}

이 작업을 수행 한 후에도 사용자 지정 IIS 오류 페이지가 계속 표시되는 경우 웹 구성 파일에서 다음 섹션이 주석 처리되었는지 (또는 비어 있는지) 확인하십시오.

<system.web>
   <customErrors mode="Off" />
</system.web>
<system.webServer>   
   <httpErrors>     
   </httpErrors>
</system.webServer>

404는 종종 웹 서버에 의해 가로 채기 때문에 응용 프로그램 수준에서 처리되지 않기 때문에이 접근 방식이 모든 경우에서 작동 할 것이라고 생각하지 않습니다.
Chris Halcrow

이 방법을 사용하는 경우 Response.End();Application_Error 처리기 끝에 a 를 추가하는 것이 좋습니다 . 이것이 없으면 주어진 세션에 대해 오류의 첫 번째 발생 만 트리거됩니다. 예를 들어 Application_Error 핸들러에 사용자 정의 오류 로깅이있을 때 문제가됩니다.
Keith

6

MVC 4에서 작업하는 경우이 솔루션을 시청할 수 있습니다 .

my에 다음 Application_Error 메서드를 추가합니다 Global.asax.

protected void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    Server.ClearError();

    RouteData routeData = new RouteData();
    routeData.Values.Add("controller", "Error");
    routeData.Values.Add("action", "Index");
    routeData.Values.Add("exception", exception);

    if (exception.GetType() == typeof(HttpException))
    {
        routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
    }
    else
    {
        routeData.Values.Add("statusCode", 500);
    }

    IController controller = new ErrorController();
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();

컨트롤러 자체는 정말 간단합니다.

public class ErrorController : Controller
{
    public ActionResult Index(int statusCode, Exception exception)
    {
        Response.StatusCode = statusCode;
        return View();
    }
}

GitHub에서 Mvc4CustomErrorPage 의 전체 소스 코드를 확인하세요 .


0

나는 같은 문제가 있었다. 당신이해야 할 일은 Views 폴더의 web.config 파일에 customErrors 속성을 추가하는 대신 프로젝트 루트 폴더의 web.config 파일에 추가해야한다는 것입니다.


0

여기에 오류 페이지를 한곳에서 완전히 사용자 정의 할 수있는 정답이 있습니다. web.config를 수정하거나 별도의 코드를 만들 필요가 없습니다.

MVC 5에서도 작동합니다.

컨트롤러에 다음 코드를 추가합니다.

        if (bad) {
            Response.Clear();
            Response.TrySkipIisCustomErrors = true;
            Response.Write(product + I(" Toodet pole"));
            Response.StatusCode = (int)HttpStatusCode.NotFound;
            //Response.ContentType = "text/html; charset=utf-8";
            Response.End();
            return null;
        }

http://www.eidias.com/blog/2014/7/2/mvc-custom-error-pages 기반


0

특정한 경우에 대해 이야기하겠습니다.

아래와 같이 HomeController에서 'PageNotFound 메서드'를 사용하는 경우

[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

작동하지 않습니다. 하지만 아래와 같이 Route 태그를 지워야합니다.

//[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

그리고 web.config에서 메서드 이름으로 변경 하면 작동합니다. 그러나 web.config에서 아래와 같은 코드를 수행하는 것을 잊지 마십시오.

<customErrors mode="On">
  <error statusCode="404" redirect="~/PageNotFound" /> 
 *// it is not "~/404" because it is not accepted url in Route Tag like [Route("404")]*
</customErrors>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.