Gestion des erreurs dans ASP.NET Core

Cet article présente quelques moyens de gérer les erreurs courantes dans les applications Web ASP.NET Core. API Web associée, voir Gestion des ASP.NET Core Web APIerreurs.

Page d'exception du développeur

La page d'exception du développeur affiche les informations détaillées de l'exception de demande. Le modèle ASP.NET Core génère le code suivant:

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

Lorsque l'application 开发环境est en cours d'exécution, le code précédemment mis en surbrillance active la page d'exception du développeur.

Le modèle est placé dans la partie avant du pipeline middleware UseDeveloperExceptionPageafin de pouvoir intercepter les exceptions levées ultérieurement dans le middleware.

Le code précédent active la page d'exception du développeur uniquement lorsque l'application s'exécute dans l'environnement de développement. Lorsque l'application s'exécute dans un environnement de production, les informations d'exception détaillées ne doivent pas être affichées publiquement. Pour plus d'informations sur la configuration des environnements, consultez Utilisation de plusieurs environnements dans ASP.NET Core.

La page des exceptions du développeur comprend les informations suivantes sur les exceptions et les demandes:

  • Trace de la pile
  • Paramètres de chaîne de requête (le cas échéant)
  • Cookie (le cas échéant)
  • Entête

Page du gestionnaire d'exceptions

Pour configurer une page de gestion des erreurs personnalisée pour l'environnement de production, utilisez le middleware de gestion des exceptions. Intergiciel:

  • Attrapez et enregistrez l'exception.
  • Réexécutez la demande dans le pipeline alternatif en utilisant le chemin indiqué. Si la réponse a été lancée, la demande ne sera pas réexécutée. /ErrorDemande de réexécution de chemin de code généré par le modèle .

Dans l'exemple suivant, UseExceptionHandlerajoutez un middleware de gestion des exceptions dans un environnement sans développement:

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

Le modèle d'application Razor Pages fournit une page "erreur" (.cshtml) et une classe PageModel (ErrorModel) dans le dossier Pages. Pour les applications MVC, le modèle de projet inclut la méthode d'opération d'erreur et la vue d'erreur du contrôleur principal.

N'utilisez pas d'attributs de méthode HTTP (tels que HttpGet) pour marquer les méthodes d'opération du gestionnaire d'erreurs. Les prédicats explicites peuvent empêcher certaines méthodes d'accès aux requêtes. Si des utilisateurs non authentifiés doivent voir l'affichage des erreurs, autorisez l'accès anonyme à la méthode.

L'exception est gérée de différentes manières selon la méthode HTTP d'origine:

  • Pour Razor Pages, créez plusieurs méthodes de gestionnaire. Par exemple, en utilisant le OnGetprocessus d'exceptions GET, en OnPostgérant l'exception POST.
  • Pour MVC, appliquez les attributs de verbe HTTP à plusieurs opérations. Par exemple, en utilisant le [HttpGet]processus d'exceptions GET, en [HttpPost]gérant l'exception POST.

Pour permettre aux utilisateurs non authentifiés d'afficher la page de gestion des erreurs personnalisée, assurez-vous qu'elle prend en charge l'accès anonyme.

Exception d'accès

Utilisez IExceptionHandlerPathFeature pour accéder à l'exception et au chemin de la demande d'origine dans le contrôleur ou la page du gestionnaire d'erreurs:

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
    
    
    public string RequestId {
    
     get; set; }
    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
    public string ExceptionMessage {
    
     get; set; }

    public void OnGet()
    {
    
    
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;

        var exceptionHandlerPathFeature =
            HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
        {
    
    
            ExceptionMessage = "File error thrown";
        }
        if (exceptionHandlerPathFeature?.Path == "/index")
        {
    
    
            ExceptionMessage += " from home page";
        }
    }
}

[! AVERTISSEMENT]
Ne fournissez pas d'informations d'erreur sensibles au client. Les erreurs dans la fourniture de services constituent un risque pour la sécurité.

Pour tester les exceptions dans l'exemple d'application:

  • Définissez l'environnement sur l'environnement de production.
  • Program.cs des webBuilder.UseStartup<Startup>();commentaires supprimés.
  • Sélectionnez "Trigger Exception" sur la page d'accueil.

Pour déclencher la page de gestion des exceptions précédente, veuillez définir l'environnement sur l'environnement de production et forcer la levée d'une exception.

Gestionnaire d'exceptions lambda

Une alternative à une page de gestionnaire d'exceptions personnalisée consiste à fournir un lambda à UseExceptionHandler. À l'aide de lambda, vous pouvez accéder à l'erreur avant de renvoyer la réponse.
L'exemple suivant montre comment utiliser lambda pour la gestion des exceptions:

if (env.IsDevelopment())
{
    
    
    app.UseDeveloperExceptionPage();
}
else
{
    
    
   app.UseExceptionHandler(errorApp =>
   {
    
    
        errorApp.Run(async context =>
        {
    
    
            context.Response.StatusCode = 500;
            context.Response.ContentType = "text/html";

            await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
            await context.Response.WriteAsync("ERROR!<br><br>\r\n");

            var exceptionHandlerPathFeature = 
                context.Features.Get<IExceptionHandlerPathFeature>();

            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
    
    
                await context.Response.WriteAsync("File error thrown!<br><br>\r\n");
            }

            await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n");
            await context.Response.WriteAsync("</body></html>\r\n");
            await context.Response.WriteAsync(new string(' ', 512)); // IE padding
        });
    });
    app.UseHsts();
}

Dans le code précédent, attendez context.Response.WriteAsync (new string ('', 512)); est ajouté afin que le navigateur Internet Explorer affiche le message d'erreur correspondant au lieu d'afficher le message d'erreur IE. Pour plus d'informations, consultez ce problème GitHub.
caveat

Ne proposez pas au client de IExceptionHandlerFeatureou de IExceptionHandlerPathFeaturemessages d'erreur sensibles. Les erreurs dans la fourniture de services constituent un risque pour la sécurité.

Pour afficher les résultats de la gestion des exceptions lambda dans l'exemple d'application, utilisez les directives de préprocesseur ProdEnvironment et ErrorHandlerLambda, puis sélectionnez «Trigger Exception» sur la page d'accueil.

UseStatusCodePages

Par défaut, les applications ASP.NET Core ne fourniront pas de page de codes d'état pour les codes d'état HTTP (tels que «404-Not Found»). L'application renvoie un code d'état et un corps de réponse vide. Pour fournir une page de codes d'état, utilisez le middleware de page de codes d'état.
Ce middleware est fourni via le package Microsoft.AspNetCore.Diagnostics.
Pour activer le gestionnaire de texte brut par défaut pour les codes d'état d'erreur courants, appelez UseStatusCodePages dans la méthode Startup.Configure:

app.UseStatusCodePages();

Appelé avant le traitement de la demande middleware UseStatusCodePages. Par exemple, il est appelé avant le middleware de fichier statique et le middleware de point de terminaison UseStatusCodePages.

Non utilisé UseStatusCodePageslorsqu'il n'y a pas de point de terminaison pour accéder à l'URL renverra un message d'erreur associé au navigateur, indiquant que le point de terminaison n'a pas été trouvé. Par exemple, accédez à Home/Privacy2. Appelez UseStatusCodePages, le navigateur renvoie:

Status Code: 404; Not Found

UseStatusCodePages Il n'est généralement pas utilisé en production car il renvoie des messages qui ne sont pas utiles à l'utilisateur.

L'intergiciel de page de code d'état n'attrape pas les exceptions. Pour fournir une page de gestion des erreurs personnalisée, veuillez utiliser 异常处理程序页.

Contient la chaîne de format UseStatusCodePages

Pour personnaliser le type de contenu et le texte de la réponse, utilisez la surcharge UseStatusCodePages qui nécessite le type de contenu et la chaîne de format:

app.UseStatusCodePages(
    "text/plain", "Status code page, status code: {0}");

Dans le code précédent, il {0}s'agit d'un espace réservé pour le code d'erreur.

Contenant du lambda UseStatusCodePages

Pour spécifier des codes de gestion d'erreur et d'écriture de réponse personnalisés, utilisez la surcharge UseStatusCodePages qui nécessite des expressions lambda:

app.UseStatusCodePages(async context =>
{
    
    
    context.HttpContext.Response.ContentType = "text/plain";

    await context.HttpContext.Response.WriteAsync(
        "Status code page, status code: " + 
        context.HttpContext.Response.StatusCode);
});

UseStatusCodePagesWithRedirects

UseStatusCodePagesWithRedirects Méthode d'extension:

  • Envoyez un code d'état "302-Found" au client.
  • Redirigez le client vers le point de terminaison de gestion des erreurs fourni dans le modèle d'URL. Le point de terminaison de gestion des erreurs affiche généralement un message d'erreur et renvoie HTTP 200.
app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}");

Le modèle d'URL peut inclure des {0}espaces réservés de code d'état , comme indiqué dans le code précédent. Si le modèle d'URL avec un tilde ~(tilde) au début, il ~sera remplacé par l'application PathBase. Lorsque vous spécifiez le point de terminaison dans l'application, créez une vue MVC ou une page Razor pour le point de terminaison. Pour obtenir des exemples de pages Razor, consultez Pages / StatusCode.cshtml dans l'exemple d'application.

Cette méthode est généralement utilisée lorsque l'application:

  • Le client doit être redirigé vers un autre point de terminaison (généralement lorsque différentes applications gèrent des erreurs). Pour les applications Web, la barre d'adresse du navigateur du client reflète le point de terminaison de redirection.
  • Le code d'état d'origine ne doit pas être conservé et renvoyé via la réponse de redirection initiale.

UseStatusCodePagesWithReExecute

UseStatusCodePagesWithReExecute Méthode d'extension:

  • Renvoyez le code d'état d'origine au client.
  • Réexécutez le pipeline de demandes en utilisant le chemin alternatif pour générer le corps de la réponse.
app.UseStatusCodePagesWithReExecute("/StatusCode","?code={0}");

Si vous pointez vers un point de terminaison dans l'application, créez une vue MVC ou une page Razor pour le point de terminaison. Assurez-vous d'être UseStatusCodePagesWithReExecuteplacé UseRoutingavant, afin que la demande puisse être redirigée vers la page d'état. Pour obtenir des exemples de pages Razor, consultez Pages / StatusCode.cshtml dans l'exemple d'application.

Cette méthode est généralement utilisée lorsque l'application doit:

  • Traitez la demande, mais ne redirigez pas vers un autre point de terminaison. Pour les applications Web, la barre d'adresse du navigateur du client reflète le point de terminaison de la demande d'origine.
  • Conservez le code d'état d'origine et renvoyez-le avec la réponse.

Les modèles d'URL et les modèles de chaînes de requête peuvent inclure des espaces réservés pour les codes d'état {0}. Le modèle d'URL doit /commencer par.

@page "{code?}"

Le point de terminaison de gestion des erreurs peut obtenir l'URL d'origine qui a généré l'erreur, comme illustré dans l'exemple suivant:

var statusCodeReExecuteFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature != null)
{
    
    
    OriginalURL =
        statusCodeReExecuteFeature.OriginalPathBase
        + statusCodeReExecuteFeature.OriginalPath
        + statusCodeReExecuteFeature.OriginalQueryString;
}

Désactiver la page de codes d'état

Pour désactiver la page de codes d'état du contrôleur MVC ou de la méthode de fonctionnement, utilisez la [SkipStatusCodePages]fonction.

Pour désactiver la méthode de gestionnaire Razor Pages ou la page de codes d'état de la demande spécifique dans le contrôleur MVC, utilisez IStatusCodePagesFeature: To disable the Razor Pages handler method or the specific request status code page in the MVC controller, use :

var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();

if (statusCodePagesFeature != null)
{
    
    
    statusCodePagesFeature.Enabled = false;
}

Code de gestion des exceptions

Le code de la page de gestion des exceptions peut également déclencher une exception. Vous devez tester minutieusement la page d'erreur de production et prendre des précautions supplémentaires pour éviter de lancer ses propres exceptions.

En-tête de réponse

Après l'envoi de l'en-tête de réponse:

  • L'application ne peut pas modifier le code d'état de la réponse.
  • Aucune page ou gestionnaire d'exception ne peut être exécuté. La réponse doit être terminée ou la connexion doit être interrompue.

Gestion des exceptions de serveur

En plus de la logique de gestion des exceptions dans l'application, il HTTP 服务器实现peut également gérer certaines exceptions. Si le serveur avant d'envoyer l'en-tête de réponse capturé à anormal, le serveur envoie une réponse qui ne contient pas le corps de 500 - Internal Server Errorla réponse. Si le serveur détecte une exception après l'envoi de l'en-tête de réponse, le serveur fermera la connexion. Les demandes qui ne peuvent pas être traitées par l'application seront traitées par le serveur. Lorsque le serveur traite la demande, toutes les exceptions qui se produisent seront gérées par la gestion des exceptions du serveur. Les pages d'erreur personnalisées appliquées, le middleware de gestion des exceptions et les filtres n'affecteront pas ce comportement.

Démarrer la gestion des exceptions

Les exceptions qui se produisent lors du démarrage de l'application ne peuvent être gérées qu'au niveau de la couche support. L'hôte peut être configuré comme, 捕获启动错误et 捕获详细错误.

Ce n'est que lorsque l'erreur se produit après la liaison adresse / port d'hôte, la couche d'hébergement peut afficher la page d'erreur de l'erreur de démarrage capturée. Si la liaison échoue:

  • La couche d'hébergement enregistrera les exceptions critiques.
  • Le processus dotnet s'est écrasé.
  • Dans le serveur HTTP Kestreln'affichera aucune page d'erreur.

Lors de l'exécution de l'application sur IIS (ou Azure Application Service) ou IIS Express, si le processus ne peut pas être démarré, le module ASP.NET Core renverra «502.5-Process failed». Pour plus d'informations, consultez Dépannage d'ASP.NET Core sur Azure App Service et IIS.

Page d'erreur de base de données

L'intergiciel de page d'erreur de base de données capture les exceptions liées à la base de données et la migration Entity Framework peut être utilisée pour résoudre ces exceptions. Lorsque ces exceptions se produisent, une réponse HTML est générée qui contient des informations détaillées sur les actions possibles pour résoudre le problème. Cette page ne doit être activée que dans un environnement de développement. Activez cette page en ajoutant du code à Startup.Configure:

if (env.IsDevelopment())
{
    
    
    app.UseDatabaseErrorPage();
}

UseDatabaseErrorPageNécessite le Microsoft.AspNetCore.Diagnostics.EntityFrameworkCorepackage NuGet.

Filtre d'exception

Dans les applications MVC, les filtres d'exception peuvent être configurés globalement ou individuellement pour chaque contrôleur ou chaque opération. Dans l'application Razor Pages, les filtres d'exception peuvent être configurés globalement ou individuellement pour chaque modèle de page. Ces filtres gèrent toutes les exceptions non gérées qui se produisent lors de l'exécution d'actions de contrôleur ou d'autres filtres. Pour plus d'informations, reportez-vous à la section ASP.NET Core 中的筛选器.

Les filtres d'exception conviennent pour intercepter les exceptions qui se produisent dans les opérations MVC, mais ils ne sont pas aussi 异常处理中间件 UseExceptionHandlerflexibles que intégrés . Nous vous recommandons de l'utiliser UseExceptionHandlersauf si vous devez effectuer la gestion des erreurs de différentes manières en fonction de l'opération MVC sélectionnée.

Erreur d'état du modèle

Pour savoir comment gérer les erreurs d'état du modèle, reportez 模型绑定-vous aux sections et 模型验证.


La gestion des erreurs

Ajouter une page de gestion des erreurs

Lors de la Startup.csconfiguration du middleware:

app.UseStatusCodePagesWithReExecute("/error/{0}");

Recommandé UseStatusCodePagesWithReExecuteau lieu de UseStatusCodePagesWithRedirectsl'ancienne exécution dans l'URL de saut d'erreur de pipeline, qui sera redirigée vers l'URL, ce qui entraîne le code d'état d'erreur http devient l'exécution normale d'une nouvelle page de 200 mètres.

Ensuite, écrivez le contrôleur d'erreur:

public class ErrorController : Controller
{
    [Route("Error/{statusCode}")]
    public IActionResult Index(int statusCode)
    {
        var statusCodeResult = HttpContext.Features.
            Get<IStatusCodeReExecuteFeature>();
        var viewModel = new ErrorViewModel
        {
            Path = statusCodeResult.OriginalPath,
            QueryString = statusCodeResult.
                OriginalQueryString,
        };
        switch (statusCode)
        {
            case 404:
                viewModel.Message = "页面未找到";
                break;
        }
        return View("Error", viewModel);
    }
}

Au fait, j'ai également défini ViewModel:

public class ErrorViewModel
{
    public int Code { get; set; }
    public string Message { get; set; }
    public string Path { get; set; }
    public string QueryString { get; set; }
}

Le code de vue ne sera pas publié, il ne s'agit que d'afficher ces messages d'erreur dans le ViewModel ~

Définir le saut d'exception global

Ajouter un middleware

app.UseExceptionHandler("/exception");

Pour écrire le contrôleur de traitement, vous devez ajouter des AllowAnonymousannotations ici pour permettre aux utilisateurs d'accéder à cette page d'exception lorsqu'ils ne sont pas connectés afin de garantir que la page d'exception peut quand même être affichée.

[AllowAnonymous]
[Route("exception")]
public IActionResult ExceptionHandler()
{
    var exception = HttpContext.Features.
        Get<IExceptionHandlerPathFeature>();
    var viewModel = new ExceptionViewModel
    {
        Path = exception.Path,
        Message = exception.Error.Message,
        StackTrace = exception.Error.StackTrace,
    };
    return View("Exception", viewModel);
}

De plus, ViewModel est défini comme suit:

public class ExceptionViewModel
{
    public string Path { get; set; }
    public string Message { get; set; }
    public string StackTrace { get; set; }
}

Je suppose que tu aimes

Origine blog.csdn.net/WuLex/article/details/113622749
conseillé
Classement