ASP.NET MVC 404错误处理

 2023-02-17    436  

问题描述

可能的副本:
如何正确处理404在ASP.NET MVC中?

我已经在 404 http错误时进行了更改ASP.NET MVC(RC 5)的处理程序,我仍然获得标准的404错误页面.我需要在IIS中改变一些东西吗?

ASP.NET MVC 404错误处理

推荐答案

又一个解决方案.

添加错误控制器或静态页面与404错误信息.

修改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),而且,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));

(可选)

说明:

有6个方案,我可以考虑ASP.NET MVC3应用程序可以生成404s的位置.

由ASP.NET生成:

  • 方案1: URL与路由表中的路由不匹配.

由ASP.NET MVC生成:

  • 方案2: URL匹配路由,但指定一个不存在的控制器.

  • 方案3: URL匹配路由,但指定不存在的操作.

手动生成:

  • 方案4: action使用httpnotfound()方法返回httpnotfoundresult.

  • 方案5:一个动作用状态代码404抛出HttpException.

  • 方案6:操作手动修改response.statuscode属性至404.

目标

  • (a)向用户显示自定义404错误页面.

  • (b)维护客户端响应的404状态代码(特别重要的SEO).

  • (c)直接发送响应,而不涉及302重定向.

解决方案尝试:自定义错误

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

此解决方案的问题:

  • 在情景(1),(4),(6)中不符合目标(a).
  • 自动不符合目标(b).它必须手动编程.
  • 不符合目标(c).

解决方案尝试:http错误

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

此解决方案的问题:

  • 只适用于IIS 7 +.
  • 在情景(2),(3),(5)中不符合目标(a).
  • 自动不符合目标(b).它必须手动编程.

解决方案尝试:用替换

的http错误

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

此解决方案的问题:

  • 只适用于IIS 7 +.
  • 自动不符合目标(b).它必须手动编程.
  • 它遮挡了应用程序级HTTP异常.例如.无法使用CustomErrors部分,System.Web.mvc.HandleErrorAttribute等.它不仅可以显示通用错误页面.

解决方案尝试customerrors和http错误

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

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

此解决方案的问题:

  • 只适用于IIS 7 +.
  • 自动不符合目标(b).它必须手动编程.
  • 在情景(2),(3),(5)中不符合目标(c).

甚至试图创建自己的库(见 http://aboutcode.net/2011/02/26/handling-not-found-with-asp-net-mvc3.html ).但之前的解决方案似乎涵盖了所有场景,而无需使用外部库的复杂性.

其他推荐答案

来自Marco的响应是最好的解决方案.我需要控制我的错误处理,我的意思是真的控制它.当然,我已经扩展了一些解决方案,并创建了一个全部错误管理系统,管理一切.我还阅读了其他博客中的这个解决方案,大多数高级开发人员似乎非常可接受.

这是我使用的最终代码:

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);
        }
    }

和我的errormanagercontroller:

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

现在,在我的动作中,我正在抛出我创建的自定义异常.我的控制器从我创建的基于自定义控制器的类继承.创建自定义基本控制器以覆盖错误处理.这是我的自定义基础控制器类:

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);
    }
}

上面代码中的”errormanager”只是一种使用基于ExceptionContext的模型的视图

我的解决方案完美地工作,我能够在我的网站上处理任何错误,并根据任何异常类型显示不同的消息.

以上所述是小编给大家介绍的ASP.NET MVC 404错误处理,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/34189.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。