web-dev-qa-db-fra.com

Asp.net mvc override OnException dans le contrôleur de base continue de se propager vers Application_Error

J'essaie de renvoyer une vue sans émettre de redirection vers l'utilisateur en fonction de certaines erreurs qui pourraient survenir dans mon application, je veux gérer les erreurs + les enregistrer dans mon contrôleur de base, je ne veux pas que l'erreur se propage jusqu'à mon Global.asax - Méthode Application_Error () car je veux que cette méthode gère toutes les autres erreurs dans mon application, par exemple l'utilisateur entre une URL fausse, quelqu'un a-t-il trouvé un moyen de contourner cela?

REMARQUE: J'ai laissé mon code commenté car j'avais une solution de contournement pour certains problèmes, cela montre également que j'ai plusieurs exceptions à gérer possible ...

EDIT: Si j'émets un RedirectToAction dans cette substitution OnException, tout fonctionne comme prévu, mais je veux seulement retourner la vue et pas de redirection ...

Ma méthode de contrôleur de base est:

    protected override void OnException(ExceptionContext filterContext)
    {
        //dont interfere if the exception is already handled
        if (filterContext.ExceptionHandled)
            return;

        //let the next request know what went wrong
        filterContext.Controller.TempData["exception"] = filterContext.Exception;

        //log exception
        _logging.Error(User.Identity.Name, ExceptionHelper.BuildWebExceptionMessage(filterContext.Exception));


        //set up redirect to my global error handler
        //if (filterContext.Exception.GetType() == typeof(NoAccessException))
        //    filterContext.Result = View(new RouteValueDictionary
        //    (new { area = "", controller = "Error", action = "PublicError" }));

        //else {
        //Only return view, no need for redirection
        filterContext.Result = View(new RouteValueDictionary
        (new { area = "", controller = "Error", action = "NoAccess" }));
        //}
        //advise subsequent exception filters not to interfere and stop
        // asp.net from showing yellow screen of death
        filterContext.ExceptionHandled = true;

        //erase any output already generated
        filterContext.HttpContext.Response.Clear();

        //base.OnException(filterContext);
    }

Cette méthode devrait gérer toutes les autres erreurs qui pourraient apparaître dans mon application, je ne veux pas que les erreurs ci-dessus soient gérées dans mon Application_Error ()

protected void Application_Error()
        {

            Exception exception = Server.GetLastError();
            // Log the exception.

            var logger = Container.Get<ILoggingService>();
            logger.Error(User.Identity.Name, ExceptionHelper.BuildWebExceptionMessage(exception));

            Response.Clear();

            HttpException httpException = exception as HttpException;

            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", "Error");

            //if (httpException == null)
            //{
            routeData.Values.Add("action", "PublicError");
            //}
            //else //It's an Http Exception, Let's handle it.
            //{
            //    switch (httpException.GetHttpCode())
            //    {
            //        case 404:
            //            // Page not found.
            //            routeData.Values.Add("action", "HttpError404");
            //            break;
            //        case 500:
            //            // Server error.
            //            routeData.Values.Add("action", "HttpError500");
            //            break;

            //        // Here you can handle Views to other error codes.
            //        // I choose a General error template  
            //        default:
            //            routeData.Values.Add("action", "General");
            //            break;
            //    }
            //}

            // Pass exception details to the target error View.
            routeData.Values.Add("error", exception);

            // Clear the error on server.
            Server.ClearError();

            // Avoid IIS7 getting in the middle
            Response.TrySkipIisCustomErrors = true;

            // Call target Controller and pass the routeData.
            IController errorController = new ErrorController();
            errorController.Execute(new RequestContext(
                 new HttpContextWrapper(Context), routeData));
        }
50
Haroon

Les éléments suivants devraient fonctionner:

protected override void OnException(ExceptionContext filterContext)
{
    if (filterContext.ExceptionHandled)
    {
        return;
    }
    filterContext.Result = new ViewResult
    {
        ViewName = "~/Views/Shared/Error.aspx"
    };
    filterContext.ExceptionHandled = true;
}

Assurez-vous également qu'aucune exception n'est levée dans cette méthode ou qu'elle se propage à Application_Error.

71
Darin Dimitrov