Programming

ASP.NET MVC 404 오류 처리

procodes 2020. 7. 1. 22:15
반응형

ASP.NET MVC 404 오류 처리


가능한 중복 :
ASP.NET MVC에서 404를 올바르게 처리하려면 어떻게해야합니까?

 

Asp.Net MVC (RC 5)의 404 Http 오류 처리기에

설명 된 변경 사항을 적용 했지만 표준 404 오류 페이지가 계속 표시됩니다. IIS에서 무언가를 변경해야합니까?


또 다른 해결책.404 오류 정보로 ErrorController 또는 정적 페이지를 추가하십시오.web.config를 수정하십시오 (컨트롤러의 경우).

<system.web>
    <customErrors mode="On" >
       <error statusCode="404" redirect="~/Errors/Error404" />
    </customErrors>
</system.web>

또는 정적 페이지의 경우

<system.web>
    <customErrors mode="On" >
        <error statusCode="404" redirect="~/Static404.html" />
    </customErrors>
</system.web>

이것은 누락 된 경로와 누락 된 동작을 모두 처리합니다.


MVC (특히 MVC3) 에서 404를 올바르게 관리하는 방법에 대해

많은

것을 조사 했으며 IMHO는 내가 생각해 낸 최고의 솔루션입니다.global.asax에서 :

public class MvcApplication : HttpApplication
{
    protected void Application_EndRequest()
    {
        if (Context.Response.StatusCode == 404)
        {
            Response.Clear();

            var rd = new RouteData();
            rd.DataTokens["area"] = "AreaName"; // In case controller is in another area
            rd.Values["controller"] = "Errors";
            rd.Values["action"] = "NotFound";

            IController c = new ErrorsController();
            c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
        }
    }
}

ErrorsController :

public sealed class ErrorsController : Controller
{
    public ActionResult NotFound()
    {
        ActionResult result;

        object model = Request.Url.PathAndQuery;

        if (!Request.IsAjaxRequest())
            result = View(model);
        else
            result = PartialView("_NotFound", model);

        return result;
    }
}

편집하다:

IoC (예 : AutoFac)를 사용하는 경우 다음을 사용하여 컨트롤러를 만들어야합니다.

var rc = new RequestContext(new HttpContextWrapper(Context), rd);
var c = ControllerBuilder.Current.GetControllerFactory().CreateController(rc, "Errors");
c.Execute(rc);

대신에

IController c = new ErrorsController();
c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));

(선택 과목)

설명:

ASP.NET MVC3 앱이 404를 생성 할 수있는 위치를 생각할 수있는 6 가지 시나리오가 있습니다.ASP.NET에서 생성 :

  • 시나리오 1 : URL이 경로 테이블의 경로와 일치하지 않습니다.

ASP.NET MVC에 의해 생성됨 :

  • 시나리오 2 :

    URL이 경로와 일치하지만 존재하지 않는 컨트롤러를 지정합니다.
  • 시나리오 3 :

    URL이 경로와 일치하지만 존재하지 않는 동작을 지정합니다.

수동 생성 :

  • 시나리오 4 :

    조치는 HttpNotFound () 메소드를 사용하여 HttpNotFoundResult를 리턴합니다.
  • 시나리오 5 :

    조치가 상태 코드 404로 HttpException을 발생시킵니다.
  • 시나리오 6 :

    조치가 Response.StatusCode 특성을 수동으로 404로 수정합니다.

Objectives

  • (A) Show a custom 404 error page to the user.

  • (B) Maintain the 404 status code on the client response (specially important for SEO).

  • (C) Send the response directly, without involving a 302 redirection.

Solution Attempt: Custom Errors

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

Problems with this solution:

  • Does not comply with objective (A) in scenarios (1), (4), (6).
  • Does not comply with objective (B) automatically. It must be programmed manually.
  • Does not comply with objective (C).

Solution Attempt: HTTP Errors

<system.webServer>
    <httpErrors errorMode="Custom">
        <remove statusCode="404"/>
        <error statusCode="404" path="App/Errors/NotFound" responseMode="ExecuteURL"/>
    </httpErrors>
</system.webServer>

Problems with this solution:

  • Only works on IIS 7+.
  • Does not comply with objective (A) in scenarios (2), (3), (5).
  • Does not comply with objective (B) automatically. It must be programmed manually.

Solution Attempt: HTTP Errors with Replace

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

Problems with this solution:

  • Only works on IIS 7+.
  • Does not comply with objective (B) automatically. It must be programmed manually.
  • It obscures application level http exceptions. E.g. can't use customErrors section, System.Web.Mvc.HandleErrorAttribute, etc. It can't only show generic error pages.

Solution Attempt customErrors and HTTP Errors

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

and

<system.webServer>
    <httpErrors errorMode="Custom">
        <remove statusCode="404"/>
        <error statusCode="404" path="App/Errors/NotFound" responseMode="ExecuteURL"/>
    </httpErrors>
</system.webServer>

Problems with this solution:

  • Only works on IIS 7+.
  • Does not comply with objective (B) automatically. It must be programmed manually.
  • Does not comply with objective (C) in scenarios (2), (3), (5).

People that have troubled with this before even tried to create their own libraries (see http://aboutcode.net/2011/02/26/handling-not-found-with-asp-net-mvc3.html). But the previous solution seems to cover all the scenarios without the complexity of using an external library.


The response from Marco is the BEST solution. I needed to control my error handling, and I mean really CONTROL it. Of course, I have extended the solution a little and created a full error management system that manages everything. I have also read about this solution in other blogs and it seems very acceptable by most of the advanced developers.

Here is the final code that I am using:

protected void Application_EndRequest()
    {
        if (Context.Response.StatusCode == 404)
        {
            var exception = Server.GetLastError();
            var httpException = exception as HttpException;
            Response.Clear();
            Server.ClearError();
            var routeData = new RouteData();
            routeData.Values["controller"] = "ErrorManager";
            routeData.Values["action"] = "Fire404Error";
            routeData.Values["exception"] = exception;
            Response.StatusCode = 500;

            if (httpException != null)
            {
                Response.StatusCode = httpException.GetHttpCode();
                switch (Response.StatusCode)
                {
                    case 404:
                        routeData.Values["action"] = "Fire404Error";
                        break;
                }
            }
            // Avoid IIS7 getting in the middle
            Response.TrySkipIisCustomErrors = true;
            IController errormanagerController = new ErrorManagerController();
            HttpContextWrapper wrapper = new HttpContextWrapper(Context);
            var rc = new RequestContext(wrapper, routeData);
            errormanagerController.Execute(rc);
        }
    }

and inside my ErrorManagerController :

        public void Fire404Error(HttpException exception)
    {
        //you can place any other error handling code here
        throw new PageNotFoundException("page or resource");
    }

Now, in my Action, I am throwing a Custom Exception that I have created. And my Controller is inheriting from a custom Controller Based class that I have created. The Custom Base Controller was created to override error handling. Here is my custom Base Controller class:

public class MyBasePageController : Controller
{
    protected override void OnException(ExceptionContext filterContext)
    {
        filterContext.GetType();
        filterContext.ExceptionHandled = true;
        this.View("ErrorManager", filterContext).ExecuteResult(this.ControllerContext);
        base.OnException(filterContext);
    }
}

The "ErrorManager" in the above code is just a view that is using a Model based on ExceptionContext

My solution works perfectly and I am able to handle ANY error on my website and display different messages based on ANY exception type.


Looks like this is the best way to catch everything.

How can I properly handle 404 in ASP.NET MVC?


In IIS, you can specify a redirect to "certain" page based on error code. In you example, you can configure 404 - > Your customized 404 error page.


What I can recomend is to look on FilterAttribute. For example MVC already has HandleErrorAttribute. You can customize it to handle only 404. Reply if you are interesed I will look example.

BTW

Solution(with last route) that you have accepted in previous question does not work in much of the situations. Second solution with HandleUnknownAction will work but require to make this change in each controller or to have single base controller.

My choice is a solution with HandleUnknownAction.

참고URL : https://stackoverflow.com/questions/717628/asp-net-mvc-404-error-handling

반응형