【问题标题】:Custom error page ,when Http error occured without changing url自定义错误页面,当发生 Http 错误而不更改 url
【发布时间】:2014-09-15 09:18:16
【问题描述】:

如何显示自定义错误页面,当发生 Http 错误而不更改 url。

当发生 Http 错误时,如何在不路由到另一个 Url 的情况下显示客户自定义错误页面。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3


    【解决方案1】:

    以下方法不会使用重定向 - 它会返回您的自定义错误 + 正确的 httpstatus 代码作为对客户端的即时响应,方法是在 application_error 方法中捕获错误,然后选择在同一响应中返回的内容,删除需要重定向。

    创建一个 ErrorController - 这允许您定制您的最终用户错误页面和状态代码。:

    [AllowAnonymous]
    public class ErrorController : Controller
    {
        public ActionResult PageNotFound()
        {
            Response.StatusCode = 404;
            return View();
        }
    
        public ActionResult ServerError()
        {
            Response.StatusCode = 500;
            return View();
        }
    
        public ActionResult UnauthorisedRequest()
        {
            Response.StatusCode = 403;
            return View();
        }
    
        //Any other errors you want to specifically handle here.
    
        public ActionResult CatchAllUrls()
        {
            //throwing an exception here pushes the error through the Application_Error method for centralised handling/logging
            throw new HttpException(404, "The requested url " + Request.Url.ToString() + " was not found");
        }
    }
    

    添加一个路由以捕获所有 url 到您的路由配置的末尾 - 这将捕获所有通过匹配现有路由尚未捕获的 404:

    routes.MapRoute("CatchAllUrls", "{*url}", new { controller = "Error", action = "CatchAllUrls" });
    

    在您的 global.asax 中:

    protected void Application_Error(object sender, EventArgs e)
        {
            Exception exception = Server.GetLastError();
    
            //Error logging omitted
    
            HttpException httpException = exception as HttpException;
            RouteData routeData = new RouteData();
            IController errorController = new Controllers.ErrorController();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("area", "");
            routeData.Values.Add("ex", exception);
    
            if (httpException != null)
            {
                //this is a basic exampe of how you can choose to handle your errors based on http status codes.
                switch (httpException.GetHttpCode())
                {
                    case 404:
                        Response.Clear();
    
                        // page not found
                        routeData.Values.Add("action", "PageNotFound");
    
                        Server.ClearError();
                        // Call the controller with the route
                        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    
                        break;
                    case 500:
                        // server error
                        routeData.Values.Add("action", "ServerError");
    
                        Server.ClearError();
                        // Call the controller with the route
                        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
                        break;
                     case 403:
                        // server error
                        routeData.Values.Add("action", "UnauthorisedRequest");
    
                        Server.ClearError();
                        // Call the controller with the route
                        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
                        break;
                     //add cases for other http errors you want to handle, otherwise HTTP500 will be returned as the default.
                    default:
                        // server error
                        routeData.Values.Add("action", "ServerError");
    
                        Server.ClearError();
                        // Call the controller with the route
                        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
                        break;
                }
            }
            //All other exceptions should result in a 500 error as they are issues with unhandled exceptions in the code
            else
            {
                routeData.Values.Add("action", "ServerError");
                Server.ClearError();
                // Call the controller with the route
                errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
            }
        }
    

    【讨论】:

      【解决方案2】:

      在web.config中添加<customErrors>标签,帮助你在系统找不到请求的url(状态码404)时重定向到Error控制器的NotFound动作方法,并重定向到错误控制器的ServerError动作方法如果系统触发内部服务器错误(状态码 500)

      <!--<Redirect to error page>-->
      <customErrors mode="On" defaultRedirect="~/Error/ServerError">
        <error redirect="~/Error/NotFound" statusCode="404" />
      </customErrors>
      <!--</Redirect to error page>-->
      

      您必须创建一个包含 ServerError 和 NotFound 操作方法的错误控制器,该操作方法呈现相关视图以向用户显示正确的消息。

      public class ErrorController : Controller
      {
          public ActionResult NotFound()
          {
              return View();
          }
          public ActionResult Error()
          {
              return View();
          }
      }
      

      编辑 2:

      为了在发生自定义错误时保持相同的 url,您需要安装 Magical Unicorn Mvc Error Toolkit 2.2.2 nuget 包。

      您可以按照以下步骤进行操作:

      1. 在 Visual Studio 中打开解决方案
      2. 转到Tools 菜单并选择Nuget Package Manager
      3. 从子菜单中选择Package Manager Console
      4. 在包管理器控制台中写入PM&gt; Install-Package MagicalUnicorn.MvcErrorToolkit

      你可以visit here for more info关于nuget包

      它将根据您的要求安装 nuget 包。

      【讨论】:

      • 在这种情况下,我的 url 正在改变,但我希望我的客户输入页面的 url 保持不变并且客户显示自定义错误页面
      • 查看我的 Edit2 进行查询
      猜你喜欢
      • 2011-03-26
      • 2011-01-17
      • 2013-04-09
      • 2011-04-20
      • 1970-01-01
      • 2016-12-03
      • 1970-01-01
      • 2020-01-21
      • 2011-06-05
      相关资源
      最近更新 更多