5

使用此处发布的博客和此处的主题,我创建了一个控制器,该控制器应处理我的所有错误页面。

在我的 Global.asax.cs 中,我有以下代码:

protected void Application_Error()
        {
            var exception = Server.GetLastError();
            var httpException = exception as HttpException;
            var routeData = new RouteData();

            Response.Clear();
            Server.ClearError();

            routeData.Values["controller"] = "Error";
            routeData.Values["action"] = "General";
            routeData.Values["exception"] = exception;
            Response.StatusCode = 500;

            if (httpException != null)
            {
                Response.StatusCode = httpException.GetHttpCode();
                switch (Response.StatusCode)
                {
                    case 403:
                        routeData.Values["action"] = "Http403";
                        break;
                    case 404:
                        routeData.Values["action"] = "Http404";
                        break;
                }
            }

            // Avoid IIS7 getting in the middle
            Response.TrySkipIisCustomErrors = true;
            IController errorsController = new ErrorController();
            HttpContextWrapper wrapper = new HttpContextWrapper(Context);
            var rc = new RequestContext(wrapper, routeData);
            errorsController.Execute(rc);
        }

我的 ErrorController 看起来像这样:

public class ErrorController : BaseController
    {
        /// <summary>
        /// Returns a default view for not having access.
        /// </summary>
        public ActionResult Unauthorized()
        {
            BaseModel viewModel = new BaseModel
                                      {
                                          LoginModel = new LogonModel(),
                                          ProfessionsTopX = GetTopXProfessions()
                                      };
            return View(viewModel);
        }

        public ActionResult General(Exception exception)
        {
            return View("Exception", exception);
        }

        public ActionResult Http404()
        {
            //This line works
            //return Content("Not found", "text/plain");

            //This line presents a blank page
            return View("404","_Layout");
        }

        public ActionResult Http403()
        {
            return View("403", "_Layout");
        }

    }

而我的 Razor View 只包含下面的一段 html;

@{
    ViewBag.Title = "404";
}

<h2>404</h2>

This is a 404 page!

当我使用返回内容时,我得到一个纯文本输出,告诉我我正在查看 404 页。但是,我希望 404 页面适合我的设计的其余部分,所以我想使用我自己的视图。但是,一旦我使用返回视图,我就会得到一个空白页。我希望遗漏一些非常明显的东西,但我没有看到。

4

2 回答 2

4

我遇到了同样的问题,终于找到了适合我的解决方案。当我在该errorsController.Execute(rc);行上放置一个断点并使用'step into'直到我遇到这个异常时,突破就来了:

The view 'Detail' or its master was not found or no view engine supports the 
searched locations. The following locations were searched:
~/Views/Errors/Detail.aspx
~/Views/Errors/Detail.ascx
~/Views/Shared/Detail.aspx
~/Views/Shared/Detail.ascx
~/Views/Errors/Detail.cshtml
~/Views/Errors/Detail.vbhtml
~/Views/Shared/Detail.cshtml
~/Views/Shared/Detail.vbhtml

异常被吞下,我认为是因为它发生在 Application_Error 方法中,并且因为我设置了Response.TrySkipIisCustomErrors = true.

看到这个错误后,我很快意识到我的问题只是名称不匹配:我的控制器实际上ErrorController没有命名为 's',而不是ErrorsController. 对我来说问题是我设置了routeData.Values["controller"] = "Errors";,这是错误的。切换它以routeData.Values["controller"] = "Error";解决问题。

请注意,您不会立即发现错误,因为您直接实例化控制器,并且如果您拼写错误的那部分将无法编译。但是在控制器内部,调用 View() 将使用RouteData我们构造并传递给RequestContext对象的实例来查找视图。因此,如果控制器名称在那里拼写错误,MVC 不知道在哪里寻找视图,并且由于 IIS 自定义错误被跳过,它会静默失败。

长话短说:检查您的控制器并查看名称。我假设如果您的控制器名称正确,但视图的文件名不匹配,会发生类似的事情。

于 2012-09-28T05:57:44.847 回答
-1

请看看这个。这是在 mvc 中实现异常处理的最佳方式。

我已经实现了相同的异常处理,但我遇到了一些问题,但你仍然可以参考这个

于 2012-07-03T19:57:18.630 回答