أفضل طريقة لتمرير الأخطاء الأخيرة لإعادة توجيه الأخطاء المخصصة؟

StackOverflow https://stackoverflow.com/questions/1127236

سؤال

كان يتساءل عما فرضه هذا الحل، إذا كانت هذه هي الطريقة الصحيحة لتمرير رسالة خطأ إلى صفحة مخصصة؟

في web.config:

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

في global.asax:

<script RunAt="server">
    void Application_Error(object sender, EventArgs e)
    {
    Exception ex = Server.GetLastError();
    if (ex != null && Session != null)
    {
        ex.Data.Add("ErrorTime", DateTime.Now);
        ex.Data.Add("ErrorSession", Session.SessionID);
        HttpContext.Current.Cache["LastError"] = ex;
    }
    }

</script>

في errored.aspx.cs:

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack) return;

    if (HttpContext.Current.Cache["LastError"] != null)
    {
        Exception ex = (Exception)HttpContext.Current.Cache["LastError"];
        if (ex.Data["ErrorTime"] != null && ex.Data["ErrorSession"] != null)
            if ((DateTime)ex.Data["ErrorTime"] > DateTime.Now.AddSeconds(-30d) && ex.Data["ErrorSession"].ToString() == Session.SessionID)
                Label1.Text = ex.InnerException.Message;
    }
}

من القضية: لا أريد أن أفعل Server.Transfer من Global.asax لأنه .. لا أعرف. بدا الخرقاء لي. تريد أن تكون قادرة على تغيير creacherrors إلى rederonly. لذلك يجب أن نقوم بحفظ استثناء آخر في مكان ما، ولكن لا يمكن أن تكون جلسة، لذلك حفظ إلى ذاكرة التخزين المؤقت ولكن مع بعض البيانات الإضافية (الوقت والجلسة) منذ ذاكرة التخزين المؤقت عالمية وترغب في التأكد من عدم إظهار خطأ خاطئ لشخص ما.


لقد غيرت الكود الخاص بي إلى حد ما. الآن هو فقط:

void Application_Error(object sender, EventArgs e)
{
    HttpContext.Current.Cache["LastError"] = Server.GetLastError().GetBaseException();
    Server.ClearError();
}

...و...

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack) return;

    if (HttpContext.Current.Cache["LastError"] != null)
    {
        Exception ex = (Exception)HttpContext.Current.Cache["LastError"];
        if (ex != null)
            Label1.Text = ex.Message;
    }
}

ملاحظة SessionID ليس هناك إذا كان مستخدم مجهول، و EX.Data.add مفتاح بالفعل سيكون هناك بالفعل خطأ يجعلني أدرك أنه من المهم استدعاء ClearError

هل كانت مفيدة؟

المحلول

أعتقد أن هذه طريقة لائحة للقيام بذلك. ليست الطريقة التي أفعلها، لكن الكود الخاص بي مطول جدا لنشر (وفي VB.NET).

شيء واحد أغيره هو صفحة الخطأ نفسها. بدلا من عرض الخطأ، فكر في إضافة مربع نص إلى صفحة الخطأ كحقل اختياري حيث يمكن للمستخدم إدخال عنوان بريده الإلكتروني وانقر فوق زر لإرسال تقرير الخطأ إليك. ثم عندما تتلقى تقرير الخطأ، يمكنك إلقاء نظرة على المشكلة والرد عليها. إنها طريقة أكثر سهولة للمستخدم للقيام بذلك وهي تعمل بشكل جيد للغاية بالنسبة للمواقع التي قمت بها.

على طول هذه الخطوط، قد ترغب أيضا في جمع بيانات النموذج، وبيانات الجلسة، وأي شيء آخر من القيمة ووضع ذلك في تقرير الخطأ أيضا. هذا يمكن أن يجعل مشاكل تشخيص أسهل بكثير.

نصائح أخرى

نحن نفعل شيئا قد يعمل أو لا يعمل من أجلك. نحن نفعل تسجيل نطاق واسع في DB. عندما نحصل على خطأ، نقوم بتسجيل الدخول وتنتج معرف خطأ. نعيد توجيه إلى الصفحة العامة مع معرف الخطأ والحصول على التفاصيل هناك.

بالطبع هذا يقع مسطحا على وجهه عند وجود الخطأ "لا يمكن الاتصال ب DB" ولكن هذا لا يحدث في كثير من الأحيان؛)

نظرا لأن ذاكرة التخزين المؤقت عالمية، فلن ينصح بذلك، كما قلت أنك قد تعرض الخطأ الخاطئ لشخص ما. يجب أن أقول أيضا أنك يجب ألا تخرج رسالة الخطأ مباشرة إلى المستخدمين النهائي لأسباب أمنية.

إلقاء نظرة على هذه المشكلة:

ASP.NET خطأ مخصص الخادم الخادم GetLasterRor فارغ

لتلخيص وضع شيء مثل ما يلي:

Server.Transfer(String.Concat("~/Error.aspx?message=", HttpUtility.UrlEncode(ex.InnerException.Message)))

بدلا من الاعتماد على ASP.NET للقيام بإعادة التوجيه باستخدام الإعدادات في قسم CreaxErrors.

يجب أن أتفق مع كل من N8WRL وستيف أن نهج أفضل سيكون لتسجيل الأخطاء في قاعدة البيانات ثم إرجاع معرف خطأ فقط للمستخدم. إنهم لا يحتاجون حقا إلى رؤية التفاصيل الفنية ومن الممكن أن يفضح هذا معلومات حساسة.

في حالتنا، ننتقل أيضا في معرف المستخدم (إذا كان ذلك متاحا) والصفحة التي حدث فيها الخطأ (طلب الطلب. لا يزال جيدا عند الوصول إلى التطبيق العالمي_error). بهذه الطريقة، يمكننا تتبع الخطأ أسهل بعض الشيء. ملاحظة أيضا أنك لست مضطرا لاستخدام Global.asax مع علامة البرنامج النصي. إذا قمت بإنشاء ملف Global.asax.cs في دليل App_Code الخاص بك، فيمكنك فقط رمز C # مباشرة (قد يعتمد هذا على نوع المشروع، على الرغم من).

Server.ClearError();

يجب وضع هذا الخط على Error.aspx.cs بعد عرض Errormessage على ما أعتقد.

كنت مسؤولا عن إنشاء صفحة خطأ مخصصة. كان كل شيء بسيطا جدا: في ملف Web.config الذي كان لدي:

<customErrors mode="On">
<error statusCode="404" redirect="~/error-pages/page-not-found.aspx?error=1"
</customErrors>

وفي Global.asax، في طريقة Application_error: بعض التعليمات البرمجية ...

Server.Transfer("~/error-pages/error.aspx");

في صفحة الخطأ المخصصة "Error.aspx": Server.ClearError();

لا أعرف بالضبط ما تم تعديله، لكن هذا لم يعمل بعد الآن. عندما يصل الرمز إلى طريقة Server.Transfer، تم دائما رفع استثناء: خطأ في تنفيذ طلب الطفل للحصول على الصفحة ...

نظرت إلى بعض الحلول وجدت أخيرا هذا واحد. قمت بتعديل التعليمات البرمجية الخاصة بي، والآن يبدو أنه يعمل:

<customErrors mode="On" defaultRedirect="~/error-pages/error.aspx">
  <error statusCode="404" redirect="~/error-pages/page-not-found.aspx?error=1" />
</customErrors>

وفي طريقة Global.asax:

Session["LastError"] = Server.GetLastError();

كما عملت مع رمز التخزين المؤقت [""]، لكنني فضل متغير الجلسة.

لذلك، شكرا على الردود.

  • لا تنس مسح الخطأ في صفحة الخطأ المخصصة. هذا مهم. أيضا، سيتم الإشارة إلى أنه لا تظهر بالضبط كل الأخطاء للمستخدم. ربما في شكل معين سهل الاستخدام. وإعطاء جميع المعلومات في ملف السجل، أو إرسالها عبر البريد الإلكتروني أو أي شيء آخر.

آمل أن يكون هذا مفيدا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top