3 votes

Pourquoi les exceptions d'ASP.NET MVC 3 sont-elles "traitées" deux fois ?

J'ai implémenté le traitement des exceptions en utilisant le code ci-dessous [Edited Start] Je ne sais pas pourquoi il appelle la vue deux fois. [Edited Done]

Contrôleur de base

public class BaseController : Controller
    {
        protected override void OnException(ExceptionContext filterContext)
        {
            if (filterContext.HttpContext.IsCustomErrorEnabled)
            {
                filterContext.ExceptionHandled = true;

                if (filterContext.Exception.GetType() == typeof(ArgumentOutOfRangeException))
                {
                    this.View("OutOfRange").ExecuteResult(this.ControllerContext);
                }
                else
                {
                    this.View("Error").ExecuteResult(this.ControllerContext);
                }
            }

            base.OnException(filterContext);
        }
    }

AccueilContrôleur

public class HomeController : BaseController
{
        public ActionResult Exception2()
        {
            throw (new ArgumentOutOfRangeException());
        }

        public ActionResult Exception3()
        {
            throw (new Exception());
        }
}

Vue des erreurs (dossier partagé uniquement)

@model System.Web.Mvc.HandleErrorInfo
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <title>Error</title>
</head>
<body>
    <h2>
        Sorry, an error occurred while processing your request.
    </h2>
    <h3>
        @if (Model != null)
        {
            <p>@Model.Exception.GetType().Name<br />
                thrown in @Model.ControllerName @Model.ActionName</p>
            <br />
            @Model.Exception
        }
    </h3>
</body>
</html>

Vue OutOfRange (dossier partagé uniquement)

@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <title>OutOfRange Exception</title>
</head>
<body>
    <div>
        <h3>
            @if (Model != null)
            {
                <p>@Model.Exception.GetType().Name<br />
                    thrown in @Model.ControllerName @Model.ActionName</p>
                <br />
                @Model.Exception
            }
        </h3>
    </div>
</body>
</html>

URL d'exécution : http://[domainName]/Home/Exception2

Ici, il fonctionne bien. [EDITION : Ici, il appelle aussi deux fois].

enter image description here

URL d'exécution : http://[domainName]/Home/Exception3

Ici, il ne fonctionne pas bien. Vous pouvez voir que "Sorry, an error occurred while processing your request." apparaît deux fois. Lorsque j'ai débogué l'application en utilisant l'URL ci-dessus, la vue d'erreur a été appelée deux fois (la première fois le modèle est nul et la deuxième fois le modèle contient une valeur). Puis-je savoir ce qui ne va pas dans mon implémentation ? enter image description here

7voto

Darin Dimitrov Points 528142

Des choses à essayer :

  1. Suppression de la valeur par défaut HandleError l'attribut de filtre d'action global de votre Global.asax s'il est présent. Lorsque vous créez une nouvelle application ASP.NET MVC 3, le modèle par défaut l'enregistre à l'intérieur de la section RegisterGlobalFilters méthode. Il faut donc commenter la ligne qui enregistre cet attribut.
  2. Activez les erreurs personnalisées dans votre web.config :

    <customErrors mode="On" />

UPDATE :

Si vous voulez passer un modèle à la Error.cshtml (car elle est fortement typée pour HandleErrorInfo ), vous pourriez faire ce qui suit :

else
{
    string controllerName = filterContext.RouteData.GetRequiredString("controller");
    string actionName = filterContext.RouteData.GetRequiredString("action");
    var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
    var result = new ViewResult
    {
        ViewName = "Error",
        ViewData = new ViewDataDictionary<HandleErrorInfo>(model)
    };
    filterContext.Result = result;
}

1voto

swapneel Points 1572

Ajouter base.OnException(filterContext); avant if (filterContext.HttpContext.IsCustomErrorEnabled)

      protected override void OnException(ExceptionContext filterContext)
      {
          base.OnException(filterContext);
         if (filterContext.HttpContext.IsCustomErrorEnabled)

      }

1voto

Andy N Points 11

J'ai eu le même problème, mais j'ai réussi à résoudre l'erreur en ajoutant :

Response.End();

A la fin de ma méthode OnException.

Je sais que ce n'est pas la solution idéale, mais cela m'a au moins permis de me sortir du pétrin jusqu'à ce que je puisse étudier une option plus complète.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X