MVC3 Пользовательские страницы ошибок дают пустой результат

Используя блог, отправленный здесь и тему здесь на SO я ' ve создал контроллер, который должен обрабатывать все мои страницы ошибок.

В моем 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 соответствовала остальной части моего дизайна, поэтому я хочу использовать свои собственные представления. Однако, как только я использую Return View, я получаю пустую страницу. Я ожидаю, что пропущу что-то очень очевидное, но я этого не вижу.

Ответ 1

У меня была такая же проблема, и я нашел решение, которое сработало для меня. Прорыв произошел, когда я поставил точку останова в строке 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 без no 's', а не ErrorsController. Проблема для меня заключалась в том, что я установил routeData.Values["controller"] = "Errors";, что неверно. Переключение на routeData.Values["controller"] = "Error"; устранило проблему.

Обратите внимание, что вы не поймаете ошибку сразу, потому что вы непосредственно создаете экземпляр контроллера, и он не будет компилироваться, если вы ошиблись в этой части. Но внутри контроллера вызов функции View() будет искать представление с использованием экземпляра RouteData, который мы создали и переданного объекту RequestContext. Поэтому, если имя контроллера написано неправильно, MVC не знает, где искать представление, и поскольку ошибки пользовательского IIS пропущены, он терпит неудачу.

Короче говоря: проверьте свой контроллер и просмотрите имена. Я предполагаю, что что-то подобное произойдет, если у вас правильное имя контроллера, но имя файла представления не совпадает.

Ответ 2

Пожалуйста, проверьте этот. Это лучший способ реализовать обработку исключений в mvc.

Я реализовал одну и ту же обработку исключений, но мне приходится сталкиваться с какой-то проблемой, но все же вы можете ссылаться на .