Обрабатывайте ошибки с помощью ErrorController, а не прямого просмотра

StackOverflow https://stackoverflow.com/questions/197414

Вопрос

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

Я думаю, что могу использовать фильтр [HandleError] для этого, но я не вижу никакого способа перенаправить его на контроллер / Действие.Единственный вариант, который я вижу, - это указать его непосредственно на вид.

Это было полезно?

Решение

HandleErrorAttribute , который поставляется с MVC, является довольно простой IExceptionFilter.

У вас есть несколько вариантов для достижения того, что, я думаю, вам нужно.

Вы можете использовать [HandleError (Type = typeof (MyException), View = " ErrorView ")] на действиях / контроллерах или реализовать свой собственный

HandleErrorAttribute не очень сложен. Я думаю, что MS рекомендует вам скопировать этот код и изменить его в соответствии с вашими требованиями.

Переопределение OnException дает вам доступ ко всей той информации, которая вам может понадобиться - контролер, действие, данные маршрута и т. д. - через ExceptionContext.

Не забудьте установить ExceptionHandled. Затем вы можете установить для filterContext.Result новый экземпляр RedirectToAction, который перенаправляет на ваш ErrorController и действие - очевидно, вы можете выставить конкретный контроллер и действие со свойствами.

Другие советы

Леппи, если вы хотите отправить результат действия, вы можете определить действие и контроллер для перенаправления при ошибке. Это хороший пример, но лично мне не нравится не использовать пользовательские страницы или http-коды для кодов

Вот и пример моего IExtenptionFilter. Мой базовый контроллер имеет IExceptionFilter по умолчанию для обработки всех не контролируемых ошибок.

[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
    Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class GenericExceptionHandlerFilter : ActionFilterAttribute, IExceptionFilter
{

    public Type ExceptionType { get; set;}
    public string RedirectToAction { get; set;}
    public string RedirectToController { get; set;}

    protected bool ApplyFilter(ExceptionContext filterContext)
    {
        Type lExceptionType = filterContext.Exception.GetType();
        return (ExceptionType == null ||
                lExceptionType.Equals(ExceptionType));
    }


    #region IExceptionFilter Members
    public void OnException(ExceptionContext filterContext)
    {

        if (ApplyFilter(filterContext))
        {
            IbfControllerLogger.Log(filterContext.Exception);

            filterContext.ExceptionHandled = true;

            #region Calculate Action Controller Error
            RouteValueDictionary lRoutes = new RouteValueDictionary(new
                {
                    action = RedirectToAction,
                    controller = String.IsNullOrEmpty(RedirectToController) ? (string)filterContext.RouteData.Values["controller"] : RedirectToController
                });
            UrlReWriterUtils.UrlReWriter(filterContext.Controller.ViewData, lRoutes);
            #endregion

            filterContext.Controller.TempData[TempDataName.C_TEMPDATA_EXCEPTIONERROR] = filterContext.Exception;
            filterContext.Result = new RedirectToRouteResult(lRoutes);
        }
    }
    #endregion

Почему бы не создать свой собственный ErrorResult, производный от ActionResult?

То, что я делаю (что может быть или не быть хорошей практикой), заключается в следующем:

При возникновении ошибки:

  • Если я ожидал этого и могу с этим справиться, я это делаю (регистрирую это с помощью ELMAH).
  • Если я ожидал этого и не могу с этим справиться, я регистрирую это в ELMAH и возвращаю ViewResult, который является моей страницей ошибок
    • Включите описание ошибки, стандартное сообщение и ссылку на то, что я делал
  • Если я этого не ожидал, мое переопределение onError в моем базовом классе контроллера выполняет предыдущий шаг
  • Все остальные ошибки, которые не могут быть обработаны, автоматически регистрируются ELMAH и желтыми экранами запроса

Большая часть моей общей обработки ошибок выполняется в базовом классе для всех моих контроллеров.Единственная проблема заключается в том, что мне приходится вручную устанавливать контроллер и значение действия в базовом классе, чтобы он мог сгенерировать ActionLink для перенаправления на странице ошибки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top