Question

J'essaie de comprendre le traitement des erreurs dans MVC. Ce que je recherche, c’est un moyen centralisé d’attraper les erreurs, de les consigner, si possible de les résoudre, si cela est nécessaire, d’effectuer d’autres actions et d’afficher enfin la bonne vue à l’utilisateur.

Je pense que je peux utiliser le filtre [HandleError] pour cela, mais je ne vois aucun moyen de le router vers un contrôleur / une action. La seule option que je vois est le pointant directement sur une vue.

Était-ce utile?

La solution

HandleErrorAttribute fourni avec MVC est un joli IExceptionFilter de base.

Vous avez quelques options pour réaliser ce que je pense que vous voulez.

Vous pouvez utiliser [HandleError (Type = typeof (MyException), View = "ErrorView "))] sur les actions / contrôleurs ou implémenter vos propres

HandleErrorAttribute n'est pas très complexe. Je pense que MS vous recommande de copier ce code et de le modifier selon vos besoins.

La substitution OnException vous donne accès à toutes les informations dont vous pourriez avoir besoin - contrôleur, action, données de route, etc. - via ExceptionContext.

N'oubliez pas de définir ExceptionHandled. Vous pouvez ensuite définir le filterContext.Result sur une nouvelle instance RedirectToAction qui redirige vers votre ErrorController et votre action - vous pouvez évidemment exposer le contrôleur et l'action spécifiques avec des propriétés.

Autres conseils

Leppi, Si vous souhaitez envoyer à Action Result, vous pouvez définir Action et le contrôleur à rediriger en cas d'erreur. C’est un bon exemple, mais personnellement, je n’aime pas interdire l’utilisation de pages personnalisées ou de codes http à codes

Voici un exemple de mon filtre d’extension. Mon contrôleur de base a un IExceptionFilter par défaut pour traiter toutes les erreurs non contrôlées.

[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

Pourquoi ne pas créer votre propre ErrorResult dérivé d’ActionResult?

Ce que je fais (ce qui peut être une bonne pratique ou non) est la suivante:

En cas d'erreur:

  • Si je m'y attendais et que je peux le gérer, je le fais (en le connectant avec ELMAH)
  • Si je m'y attendais et que je ne peux pas le gérer, je le connecte à ELMAH et renvoie un ViewResult correspondant à ma page d'erreur.
    • Incluez une description de l'erreur, un message standard et un lien vers ce que je faisais
  • Si je ne m'y attendais pas, mon remplacement d'OnError dans ma classe de contrôleur de base effectue l'étape précédente
  • Toutes les autres erreurs qui ne peuvent pas être traitées sont automatiquement enregistrées par ELMAH et la requête yellowscreens

La plupart de mes erreurs génériques sont traitées dans la classe de base de tous mes contrôleurs. Le seul problème est que je dois définir manuellement un contrôleur et une valeur d'action dans la classe de base afin qu'elle puisse générer un ActionLink pour la redirection dans la page d'erreur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top