ASP.NET page d'erreur personnalisée - Serveur.GetLastError () est null

j'ai une page d'erreur personnalisée établie pour mon application:

<customErrors mode="On" defaultRedirect="~/errors/GeneralError.aspx"
/>

Dans Global.asax, Application_Error (), le code suivant fonctionne pour obtenir les détails de l'exception:

  Exception ex = Server.GetLastError();
  if (ex != null)
    {
        if (ex.GetBaseException() != null)
            ex = ex.GetBaseException();
    }

au moment où j'arrive à ma page d'erreur (~/errors/GeneralError.aspx.cs), à un Serveur.GetLastError () est null

est-ce que je peux obtenir les détails de l'exception sur la Page D'erreur, plutôt que dans Global.asax.cs ?

ASP.NET 3.5 sur Vista / IIS7

109
demandé sur nailitdown 2008-12-05 08:57:01

10 réponses

regardant de plus près mon web.configuration de la configuration, un des commentaires dans ce message est très utile

in asp.net 3.5 sp1 il y a un nouveau paramètre redirectMode

pour que nous puissions modifier customErrors pour ajouter ce paramètre:

<customErrors mode="RemoteOnly" defaultRedirect="~/errors/GeneralError.aspx" redirectMode="ResponseRewrite" />

le mode ResponseRewrite nous permet de charger la" page D'erreur " sans rediriger le navigateur, de sorte que l'URL reste la même, et fait important pour moi, l'information d'exception n'est pas perdue.

133
répondu nailitdown 2016-03-06 21:23:41

OK, j'ai trouvé ce post: http://msdn.microsoft.com/en-us/library/aa479319.aspx

avec ce diagramme très illustratif:

diagramme http://i.msdn.microsoft.com/Aa479319.customerrors_01 (en-us,MSDN.10).gif

essentiellement, pour obtenir ces détails exceptionnels, je dois les stocker moi-même dans Global.asax, pour une récupération ultérieure sur ma page d'erreur personnalisée.

il semble que le meilleur moyen est de faire le gros du travail Mondial.asax, avec les pages d'erreur personnalisées traitant le contenu utile plutôt que la logique.

36
répondu nailitdown 2008-12-05 06:23:32

une combinaison de ce que NailItDown et Victor ont dit. La façon préférée / facile est d'utiliser votre Global.Asax pour stocker l'erreur et ensuite rediriger vers votre page d'erreur personnalisée.

Global.asax :

    void Application_Error(object sender, EventArgs e) 
{
    // Code that runs when an unhandled error occurs
    Exception ex = Server.GetLastError();
    Application["TheException"] = ex; //store the error for later
    Server.ClearError(); //clear the error so we can continue onwards
    Response.Redirect("~/myErrorPage.aspx"); //direct user to error page
}

En outre, vous devez configurer votre "151960920 web".config :

  <system.web>
    <customErrors mode="RemoteOnly" defaultRedirect="~/myErrorPage.aspx">
    </customErrors>
  </system.web>

et enfin, faire tout ce dont vous avez besoin à l'exception que vous avez stocké dans votre erreur page :

protected void Page_Load(object sender, EventArgs e)
{

    // ... do stuff ...
    //we caught an exception in our Global.asax, do stuff with it.
    Exception caughtException = (Exception)Application["TheException"];
    //... do stuff ...
}
19
répondu rlb.usa 2013-09-08 11:03:54

essayez d'utiliser quelque chose comme Server.Transfer("~/ErrorPage.aspx"); de la méthode Application_Error() de global.asax.cs

puis de l'intérieur de Page_Load() D'ErrorPage.aspx.cs vous devriez être bien de faire quelque chose comme: Exception exception = Server.GetLastError().GetBaseException();

Server.Transfer() semble garder l'exception traîner autour.

6
répondu 2009-04-23 04:27:36

bien qu'il y ait plusieurs bonnes réponses ici, je dois souligner que ce n'est pas une bonne pratique d'Afficher des messages d'exception système sur les pages d'erreur (ce qui est ce que je suppose que vous voulez faire). Vous risquez de révéler des choses que vous ne souhaitez pas le faire à des utilisateurs malveillants. Par exemple, les messages D'exception Sql Server sont très verbeux et peuvent donner le nom d'utilisateur, le mot de passe et les informations de schéma de la base de données en cas d'erreur. Cette information ne doit pas être affichée à une fin utilisateur.

5
répondu Phil 2011-06-07 20:39:08

une considération importante que je pense que tout le monde manque ici est un scénario d'équilibrage de la charge (web farm). Depuis le serveur qui exécute global.asax peut être différent que le serveur qui est à propos de l'exécution de la page d'erreur personnalisée, le rangement de l'objet d'exception dans L'Application n'est pas fiable.

je suis toujours à la recherche d'une solution fiable à ce problème dans une configuration de ferme web, et/ou une bonne explication de MS quant à la raison pour laquelle vous ne pouvez tout simplement pas exception avec le serveur.GetLastError sur la page d'erreur personnalisée comme vous pouvez dans global.ASAX Application_Error.

P.S. il est dangereux de stocker des données dans la collection de L'Application sans d'abord les verrouiller et ensuite les déverrouiller.

4
répondu Leonard Lobel 2010-06-05 20:23:01

voici ma solution..

Dans Global.aspx:

void Application_Error(object sender, EventArgs e)
    {
        // Code that runs when an unhandled error occurs

        //direct user to error page 
        Server.Transfer("~/ErrorPages/Oops.aspx"); 
    }

In Oops.aspx:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadError(Server.GetLastError()); 
    }

    protected void LoadError(Exception objError)
    {
        if (objError != null)
        {
            StringBuilder lasterror = new StringBuilder();

            if (objError.Message != null)
            {
                lasterror.AppendLine("Message:");
                lasterror.AppendLine(objError.Message);
                lasterror.AppendLine();
            }

            if (objError.InnerException != null)
            {
                lasterror.AppendLine("InnerException:");
                lasterror.AppendLine(objError.InnerException.ToString());
                lasterror.AppendLine();
            }

            if (objError.Source != null)
            {
                lasterror.AppendLine("Source:");
                lasterror.AppendLine(objError.Source);
                lasterror.AppendLine();
            }

            if (objError.StackTrace != null)
            {
                lasterror.AppendLine("StackTrace:");
                lasterror.AppendLine(objError.StackTrace);
                lasterror.AppendLine();
            }

            ViewState.Add("LastError", lasterror.ToString());
        }
    }

   protected void btnReportError_Click(object sender, EventArgs e)
    {
        SendEmail();
    }

    public void SendEmail()
    {
        try
        {
            MailMessage msg = new MailMessage("webteam", "webteam");
            StringBuilder body = new StringBuilder();

            body.AppendLine("An unexcepted error has occurred.");
            body.AppendLine();

            body.AppendLine(ViewState["LastError"].ToString());

            msg.Subject = "Error";
            msg.Body = body.ToString();
            msg.IsBodyHtml = false;

            SmtpClient smtp = new SmtpClient("exchangeserver");
            smtp.Send(msg);
        }

        catch (Exception ex)
        {
            lblException.Text = ex.Message;
        }
    }
4
répondu user825345 2013-03-05 20:59:46

ceci lié à ces 2 sujets ci-dessous, je veux obtenir à la fois GetHtmlErrorMessage et Session sur la page D'erreur.

Session is null after Responderewrite

pourquoi HttpContext.Session null quand redirectMode = Reponserewrite

j'ai essayé et voir la solution qui n'a pas besoin Server.Transfer() or Response.Redirect()

tout d'abord: supprimer la réponse sur le web.config

Web.config

<customErrors defaultRedirect="errorHandler.aspx" mode="On" />

Puis Mondial.asax

    void Application_Error(object sender, EventArgs e)
    {
         if(Context.IsCustomErrorEnabled)
         {     
            Exception ex = Server.GetLastError();
            Application["TheException"] = ex; //store the error for later
         }
    }

puis errorHandler.aspx.cs

        protected void Page_Load(object sender, EventArgs e)
            {       
                string htmlErrorMessage = string.Empty ;
                Exception ex = (Exception)Application["TheException"];
                string yourSessionValue = HttpContext.Current.Session["YourSessionId"].ToString();

                //continue with ex to get htmlErrorMessage 
                if(ex.GetHtmlErrorMessage() != null){              
                    htmlErrorMessage = ex.GetHtmlErrorMessage();
                }   
                // continue your code
            }

pour les références

http://www.developer.com/net/asp/article.php/3299641/ServerTransfer-Vs-ResponseRedirect.htm

2
répondu Bao 2017-05-23 12:10:36

je pense que vous avez plusieurs options.

vous pouvez stocker la dernière Exception dans la Session et la récupérer à partir de votre page d'erreur personnalisée; ou vous pouvez simplement rediriger vers votre page d'erreur personnalisée dans L'événement Application_error. Si vous choisissez ce dernier, vous voulez vous assurer d'utiliser le serveur.Méthode de transfert.

1
répondu Victor 2008-12-05 19:05:15

ça a marché pour moi. dans MVC 5



in ~\Global.asax

void Application_Error(object sender, EventArgs e)
{
    FTools.LogException();
    Response.Redirect("/Error");
}



dans ~\Controllers créer ErrorController.cs

using System.Web.Mvc;

namespace MVC_WebApp.Controllers
{
    public class ErrorController : Controller
    {
        // GET: Error
        public ActionResult Index()
        {
            return View("Error");
        }
    }
}



dans ~\Models créer FunctionTools.cs

using System;
using System.Web;

namespace MVC_WebApp.Models
{
    public static class FTools
    {
        private static string _error;
        private static bool _isError;

        public static string GetLastError
        {
            get
            {
                string cashe = _error;
                HttpContext.Current.Server.ClearError();
                _error = null;
                _isError = false;
                return cashe;
            }
        }
        public static bool ThereIsError => _isError;

        public static void LogException()
        {
            Exception exc = HttpContext.Current.Server.GetLastError();
            if (exc == null) return;
            string errLog = "";
            errLog += "**********" + DateTime.Now + "**********\n";
            if (exc.InnerException != null)
            {
                errLog += "Inner Exception Type: ";
                errLog += exc.InnerException.GetType() + "\n";
                errLog += "Inner Exception: ";
                errLog += exc.InnerException.Message + "\n";
                errLog += "Inner Source: ";
                errLog += exc.InnerException.Source + "\n";
                if (exc.InnerException.StackTrace != null)
                {
                    errLog += "\nInner Stack Trace: " + "\n";
                    errLog += exc.InnerException.StackTrace + "\n";
                }
            }
            errLog += "Exception Type: ";
            errLog += exc.GetType().ToString() + "\n";
            errLog += "Exception: " + exc.Message + "\n";
            errLog += "\nStack Trace: " + "\n";
            if (exc.StackTrace != null)
            {
                errLog += exc.StackTrace + "\n";
            }
            _error = errLog;
            _isError = true;
        }
    }
}



dans ~\Views créer un dossier Error et dans ~\Views\Error créer Error.cshtml

@using MVC_WebApp.Models
@{
    ViewBag.Title = "Error";
    if (FTools.ThereIsError == false)
    {
        if (Server.GetLastError() != null)
        {
            FTools.LogException();
        }
    }
    if (FTools.ThereIsError == false)
    {
        <br />
        <h1>No Problem!</h1>
    }
    else
    {
        string log = FTools.GetLastError;
        <div>@Html.Raw(log.Replace("\n", "<br />"))</div>
    }
}



si vous inscrivez cette adresse localhost/Error open page Whithout Error




et si une erreur se produit error occurs

comme peut l'être au lieu d'Afficher des erreurs, variable 'log' à stocker dans la base de données



Source: Microsoft ASP.Net

1
répondu M.R.T2017 2018-06-14 17:55:27