web-dev-qa-db-fra.com

Gérer l'exception dans le noyau asp.net?

J'ai une application principale asp.net. L'implémentation de la méthode configure redirige l'utilisateur vers la page "Erreur" lorsqu'il y a une exception (dans un environnement non développé)

Cependant, cela ne fonctionne que si l'exception se produit à l'intérieur du contrôleur. Si une exception se produit en dehors du contrôleur, par exemple dans mon middleware personnalisé, l'utilisateur n'est pas redirigé vers la page d'erreur.

Comment rediriger l'utilisateur vers la page "Erreur" s'il y a une exception dans le middleware.

     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseApplicationInsightsRequestTelemetry();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseApplicationInsightsExceptionTelemetry();

        app.UseStaticFiles();
        app.UseSession();
        app.UseMyMiddleware();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

mise à jour 1
J'ai mis à jour le code ci-dessus avec les deux lignes suivantes qui manquaient dans le message initial.

        app.UseSession();
        app.UseMyMiddleware();

J'ai également trouvé pourquoi app.UseExceptionHandler N'a pas pu rediriger vers la page d'erreur.
Lorsqu'il y a une exception dans mon code middleware, app.UseExceptionHandler("\Home\Error") est redirigé vers \Home\Error Comme prévu; mais comme il s'agit d'une nouvelle demande, mon middleware s'exécutait à nouveau et lançait de nouveau une exception.
Donc, pour résoudre le problème, j'ai changé mon middleware pour exécuter uniquement if context.Request.Path != "/Home/Error"

Je ne sais pas si c'est la bonne façon de résoudre ce problème, mais son fonctionnement.

public class MyMiddleWare
{
    private readonly RequestDelegate _next;
    private readonly IDomainService _domainService;

    public MyMiddleWare(RequestDelegate next, IDomainService domain)
    {
        _next = next;
        _domainService = domain;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Path != "/Home/Error")
        {
            if (context.User.Identity.IsAuthenticated && !context.Session.HasKey(SessionKeys.USERINFO))
            {           
                // this method may throw exception if domain service is down
                var userInfo = await _domainService.GetUserInformation(context.User.Name).ConfigureAwait(false);                    

                context.Session.SetUserInfo(userInfo);
            }
        }

        await _next(context);
    }
}

public static class MyMiddleWareExtensions
{
    public static IApplicationBuilder UseMyMiddleWare(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<MyMiddleWare>();
    }
 }
15
LP13

Vous pouvez utiliser pour gérer les exceptions UseExceptionHandler(), mettez ce code dans votre Startup.cs.

UseExceptionHandler peut être utilisé pour gérer les exceptions globalement. Vous pouvez obtenir tous les détails de l'objet d'exception comme Stack Trace, Inner exception et autres. Et puis vous pouvez les montrer à l'écran. ici

Ici, vous pouvez en savoir plus sur ce middleware de diagnostic et découvrir comment utiliser IExceptionFilter et en créant votre propre gestionnaire d'exceptions personnalisé.

   app.UseExceptionHandler(
                options =>
                {
                    options.Run(
                        async context =>
                        {
                            context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
                            context.Response.ContentType = "text/html";
                            var ex = context.Features.Get<IExceptionHandlerFeature>();
                            if (ex != null)
                            {
                                var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.StackTrace}";
                                await context.Response.WriteAsync(err).ConfigureAwait(false);
                            }
                        });
                }
            );

Vous devez également supprimer le paramètre par défaut comme UseDeveloperExceptionPage(), si vous l'utilisez, il affiche toujours la page d'erreur par défaut.

   if (env.IsDevelopment())
        {
            //This line should be deleted
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }
18
M. Wiśnicki

Vous devez écrire votre propre middleware pour gérer la gestion des exceptions personnalisées. Et assurez-vous de l'ajouter vers le début (le premier si possible) de votre pile de middleware car les exceptions qui se produisent dans le middleware qui est "plus tôt" dans une pile ne seront pas gérées.

Exemple:

public class CustomExceptionMiddleware
{
    private readonly RequestDelegate _next;

    public CustomExceptionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try 
        {
            await _next.Invoke(context);
        } 
        catch (Exception e) 
        {
            // Handle exception
        }
    }
}
6
Andrius