ASP.NET कस्टम त्रुटि पेज - Server.GetLastError () शून्य है


112

मेरे पास मेरे आवेदन के लिए एक कस्टम त्रुटि पृष्ठ है:

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

Global.asax, Application_Error () में, निम्न कोड अपवाद विवरण प्राप्त करने के लिए काम करता है:

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

जब तक मैं अपनी त्रुटि पृष्ठ (~ / त्रुटियों / GeneralError.aspx.cs), Server.GetLastError () के लिए अशक्त है

क्या Global.asax.cs के बजाय त्रुटि पृष्ठ पर अपवाद विवरण प्राप्त करने का कोई तरीका है?

ASP.NET 3.5 विस्टा / IIS7 पर


कासिनी के साथ Win7 पर ASP.NET 4.0 पर भी लागू होता है
Marcel

"<customErrors मोड =" रिमोटऑनलाइन "defaultRedirect =" ~ / त्रुटियों / GeneralError.aspx "redirectMode =" ResponseRewrite "/>" को पुष्ट उत्तर के रूप में
जोड़ें

जवाबों:


137

मेरे web.config सेट अप पर अधिक बारीकी से देखते हुए, इस पोस्ट में से एक टिप्पणी बहुत उपयोगी है

asp.net 3.5 sp1 में एक नया पैरामीटर redirectMode है

इसलिए हम customErrorsइस पैरामीटर को जोड़ने के लिए संशोधन कर सकते हैं :

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

ResponseRewriteमोड हमें ब्राउज़र रीडायरेक्ट किए बिना «त्रुटि पेज» लोड करने के लिए है, तो यूआरएल रहता ही अनुमति देता है, और मेरे लिए महत्वपूर्ण बात, अपवाद जानकारी नहीं खोया है।


4
यह मेरे लिए काम नहीं किया। अपवाद की जानकारी खो गई है। मैं Application_Error () में सत्र में इसे संग्रहीत करूंगा और अपने त्रुटि पृष्ठ के Page_Load () हैंडलर में इसे वापस खींचूंगा।
ब्रायनके

2
यह सभी प्रलेखन में आदर्श होना चाहिए। यह बहुत अच्छा है मुझे अब पुराने व्यवहार का समर्थन करने का कोई कारण नहीं दिखता है। जब तक स्थिति कोड सही है तब तक मूल अनुरोध URL को बरकरार रखने (ब्राउज़र पुनर्निर्देशित नहीं करने) के साथ कोई समस्या नहीं होनी चाहिए। वास्तव में यह HTTP के अनुसार अधिक सही है क्योंकि प्रतिक्रिया कोड अनुरोधित URL से संबंधित है, साझा त्रुटि पृष्ठ अनुरोध नहीं। पॉइंटर के लिए धन्यवाद मैंने उस नई सुविधा को याद किया!
टोनी वॉल

यह UpdatePanels के अंदर नियंत्रण द्वारा ट्रिगर अपवादों के साथ काम नहीं करता है ; त्रुटि पृष्ठ अब प्रदर्शित नहीं होगा।
सैम

2
चूंकि यह एक पुराना जवाब है, जो मेरी टिप्पणी को साबित करने के लिए इस अच्छे को एक प्रतिक्रिया प्रदान करता है। रीडायरेक्टम में रिस्पेक्टमाइट मान Asp.Net 4.5
Sundara Prabu

38

ठीक है, मुझे यह पोस्ट मिली: http://msdn.microsoft.com/en-us/library/aa479319.aspx

इस बहुत ही आकर्षक चित्र के साथ:

आरेख
(स्रोत: microsoft.com )

संक्षेप में, उन अपवाद विवरणों को प्राप्त करने के लिए मुझे खुद को Global.asax में संग्रहीत करने की आवश्यकता है, बाद में मेरे कस्टम त्रुटि पृष्ठ पर पुनर्प्राप्ति के लिए।

ऐसा लगता है कि Global.asax में बल्क का काम करने का सबसे अच्छा तरीका है, कस्टम एरर पेजेस में लॉजिक के बजाय मददगार कंटेंट को हैंडल करना।


18

नेल इटडाउन और विक्टर ने जो कहा, उसका एक संयोजन। पसंदीदा / सबसे आसान तरीका त्रुटि को संग्रहीत करने के लिए अपने Global.Asax का उपयोग करना है और फिर अपने कस्टम त्रुटि पृष्ठ पर रीडायरेक्ट करना है।

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
}

इसके अलावा, आपको अपना web.config सेट करना होगा :

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

और अंत में, जो कुछ भी आपको अपने त्रुटि पृष्ठ में संग्रहीत अपवाद के साथ करने की आवश्यकता है उसे करें :

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 ...
}

35
यदि आप इसे एप्लिकेशन में स्टोर करते हैं, तो सिस्टम के अन्य सभी उपयोगकर्ताओं के बारे में क्या है। क्या यह सत्र में नहीं होना चाहिए?
ब्रायनके

11
वास्तव में, यह एक बहुत बुरा तरीका है जो अनुप्रयोग ["TheException"] पर इसे स्टोर कर रहा है
जूनियर मेहेले जूल

4
इसके अलावा, यदि आप प्रति उपयोगकर्ता कई "टैब" का समर्थन करना चाहते हैं, तो आप अपवाद को सत्र स्टोर में एक अनूठी कुंजी देना चाह सकते हैं और फिर त्रुटि पृष्ठ पर पुनर्निर्देशित करते समय एक कुंजी को क्वेरिस्ट्रिंग पैरामीटर के रूप में शामिल कर सकते हैं।
एंडर्स फजल्डस्टैड

5
+1 लेकिन ध्यान रखें कि Application[]यह एक वैश्विक वस्तु है। सैद्धांतिक रूप से आपके पास एक दौड़ की स्थिति हो सकती है जहां एक दूसरा पृष्ठ त्रुटि को अधिलेखित करता है। हालांकि, चूंकि Session[]हमेशा त्रुटि स्थितियों के तहत उपलब्ध नहीं होता है, मुझे लगता है कि यह बेहतर विकल्प है।
एंडोमर

3
अपवाद को संग्रहीत करने और GUID को कस्टम त्रुटि पृष्ठ के पैरामीटर के रूप में पास करने के लिए उपयोग की जाने वाली कुंजी में बस एक नया GUID उपसर्ग जोड़ें।
स्टीवजीएसडी

6

Global.asax.cs Server.Transfer("~/ErrorPage.aspx");की Application_Error()विधि के भीतर से जैसे कुछ का उपयोग करने का प्रयास करें

फिर Page_Load()ErrorPage.aspx.cs के भीतर से आपको कुछ करने के लिए ठीक होना चाहिए:Exception exception = Server.GetLastError().GetBaseException();

Server.Transfer() अपवाद को लटकाए रखने के लिए लगता है।


यह है कि मेरे आवेदन ने यह कैसे किया, और 99% त्रुटियों के लिए इसने काफी अच्छा काम किया। लेकिन आज मैं एक अपवाद के रूप में आया था जो प्रतिपादन चरण के दौरान होता है। यदि आप Server.Transferकिसी पृष्ठ के आधे-अधूरे हैं, तो आपके द्वारा हस्तांतरित किए गए पृष्ठ के HTML को केवल जो कुछ भी पहले से ही प्रदान किया गया है, उसे संक्षिप्त कर दिया जाता है। तो आप आधे से टूटे हुए पृष्ठ के साथ समाप्त हो सकते हैं, उसके बाद नीचे त्रुटि पृष्ठ के साथ।
केविन

किसी कारण से, Server.Transfer () में समस्याएँ होती हैं और त्रुटि बिल्कुल भी प्रदर्शित नहीं होती है। और इसलिए, मैं इस पद्धति का उपयोग करने की सलाह नहीं देता। बस ऊपर दिए गए सुझाव के अनुसार web.config लाइन का उपयोग करें (<customErrors mode = "RemoteOnly" defaultRedirect = "~ / त्रुटियाँ / GeneralError.aspx" redirectMode = "ResponseRewrite />>) और यह ठीक काम करता है
नरेश मित्तल

5

जब भी यहां कई अच्छे उत्तर हैं, मुझे यह बताना होगा कि त्रुटि पृष्ठों पर सिस्टम अपवाद संदेश प्रदर्शित करने के लिए यह अच्छा अभ्यास नहीं है (जो मैं यह मान रहा हूं कि आप करना चाहते हैं)। आप अनजाने में उन चीजों को प्रकट कर सकते हैं जिन्हें आप दुर्भावनापूर्ण उपयोगकर्ताओं के लिए नहीं करना चाहते हैं। उदाहरण के लिए Sql Server अपवाद संदेश बहुत क्रियात्मक हैं और त्रुटि होने पर उपयोगकर्ता का नाम, पासवर्ड और डेटाबेस की स्कीमा जानकारी दे सकते हैं। वह जानकारी अंतिम उपयोगकर्ता को प्रदर्शित नहीं की जानी चाहिए।


1
मेरे मामले में मैं केवल बैक एंड उपयोग के लिए अपवाद जानकारी चाहता था, लेकिन यह अच्छी सलाह है।
नाखून काटकर

2
सवाल का जवाब नहीं देता।
अर्ने एवरसन

5

यहाँ मेरा समाधान है ..

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"); 
    }

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

एक महत्वपूर्ण विचार है कि मुझे लगता है कि हर कोई यहाँ याद कर रहा है एक लोड-संतुलन (वेब ​​फार्म) परिदृश्य है। चूंकि सर्वर जो Global.asax को निष्पादित कर रहा है, वह सर्वर से भिन्न हो सकता है जो कस्टम त्रुटि पेज को निष्पादित करने के बारे में है, अनुप्रयोग में अपवाद ऑब्जेक्ट को चोरी करना विश्वसनीय नहीं है।

मैं अभी भी एक वेब फ़ार्म कॉन्फ़िगरेशन में इस समस्या का एक विश्वसनीय समाधान ढूंढ रहा हूँ, और / या एमएस से एक अच्छी व्याख्या करता हूं कि आप केवल कस्टम त्रुटि पृष्ठ पर Server.GetLastError के साथ अपवाद क्यों नहीं उठा सकते हैं। in Global.asax Application_Error

PS यह अनुप्रयोग संग्रह में डेटा को पहले लॉक किए बिना और फिर उसे अनलॉक करने के लिए असुरक्षित है।


यह केवल तभी होगा जब आप क्लाइंट-साइड रीडायरेक्ट कर रहे हों। सर्वर-ट्रांसफ़र करते समय, यह सभी एक अनुरोध का हिस्सा होता है, इसलिए application_error -> page_load सभी फ़ार्म में एक सर्वर पर, क्रम में होगा।
davewasthere

2

नीचे इन 2 विषयों से संबंधित है, मैं GetHtmlErrorMessage और सत्र दोनों त्रुटि पृष्ठ पर प्राप्त करना चाहता हूं।

ResponseRewrite के बाद सत्र शून्य है

RedirectMode = ResponseRewrite होने पर HttpContext.Session null क्यों है

मैंने कोशिश की और समाधान देखा जिसकी कोई आवश्यकता नहीं है Server.Transfer() or Response.Redirect()

पहला: web.config में ResponseRewrite को हटा दें

web.config

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

फिर Global.asax

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

फिर 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
            }

संदर्भ के लिए

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


2

इसने मेरे लिए काम किया। MVC 5 में


में ~\Global.asax

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


में ~\ControllersबनाएंErrorController.cs

using System.Web.Mvc;

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


में ~\Modelsबनाएं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;
        }
    }
}


में ~\Viewsफ़ोल्डर बनाएँ Error और में ~\Views\Errorबनाएं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>
    }
}


यदि आप इस पते को दर्ज करते हैं localhost/Error खुले पृष्ठ Whithout त्रुटि



और अगर कोई त्रुटि होती है त्रुटि होती है

जैसा कि त्रुटियों को प्रदर्शित करने के बजाय, डेटाबेस में संग्रहीत करने के लिए चर 'लॉग' हो सकता है


स्रोत: Microsoft ASP.Net


1

मुझे लगता है कि आपके पास यहां कुछ विकल्प हैं।

आप सत्र में अंतिम अपवाद संग्रहीत कर सकते हैं और इसे अपने कस्टम त्रुटि पृष्ठ से पुनर्प्राप्त कर सकते हैं; या आप Application_error घटना के भीतर अपने कस्टम त्रुटि पृष्ठ पर पुनर्निर्देशित कर सकते हैं। यदि आप बाद वाला चुनते हैं, तो आप सुनिश्चित करें कि आप Server.Transfer विधि का उपयोग करना चाहते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.