ما هي أفضل طريقة لإرسال أخطاء التطبيق وسجلات عبر الإنترنت إلى المطورين؟

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

سؤال

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

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

لقد فكرت في استخدام إما SMTPClient. أو أ خدمة ويب لإرسال المعلومات. قد لا تعمل SMTPClient لأن جدران الحماية قد تمنع وصول SMTP الصادر. هل ستؤدي خدمة الويب إلى إرسال كمية كبيرة من البيانات (يحتمل أن 1+ ميغابايت)؟

ما الذي توصي به أفضل طريقة للحصول على تقارير خطأ نقل التطبيق مباشرة إلى المطورين للمراجعة؟

تعديل: توضيح: هذا تطبيق ويندوز وعندما يحدث خطأ، أرغب في طرح مربع حوار يطلب إرسال الخطأ. سؤالي هو حول الآلية لإرسال سجل الخطأ من التطبيق لي (المطور) عبر الإنترنت.

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

المحلول

نستخدم 3 طرق حيث أعمل

  • SMTP إلى صندوق بريد مخصص. هذا يتطلب كثيرا من التكوين والرقص حولها مع إدارات تكنولوجيا المعلومات "كبيرة للشركات" للعمل ما هو خادم البريد الخاص بهم وكيفية المصادقة ضده وإرساله عبره. ثم هناك برامج مثل Norton Internet Security التي يمكن أن تمنع حركة مرور SMTP الصادرة على جهاز العميل الذي يرمي محارفا إضافيا في الأعمال.
  • تقديم إلى ASMX على خادمنا. هذه هي الطريقة المفضلة لدينا، ولكن الكثير من الأشياء يمكن أن تحصل في الطريق. إنها الوكلاء بشكل رئيسي، لكن Norton يمكن أن يتخطى ويوقفك. إذا كان هناك وكيل مشارك، فهرب بعيدا :-)
  • وظيفة HTTP باستخدام HTTPWebRequest و MIME Typ of MultiPart / form-form. كما أن لديها مشاكل الوكيل وجدار الحماية، ولكن يمكن أن تعمل في بعض الأحيان حيث يفشل تقديم ASMX.

حظ سعيد. أنت على حق في ذلك كثير أسهل في التصحيح إذا كنت قد حصلت على تتبع المكدس وربما حتى سكيين ما يفعله المستخدم القديم الفقراء.

نصائح أخرى

بعض الطرق التي تجعل المستخدم يعرف أنك تعني القيام بذلك. اطلب منهم عن وكيل، اسألهم عن خادم بريد إلكتروني، شيء من هذا القبيل.

سيحصل الأفق الأيمن على عصبي حقيقي إذا اكتشفوا أنك تفتح مقبس أو شيء من هذا القبيل وإرسال البيانات دون إخطار.

وهي محقة في ذلك.

أود أن أقترح عدم إرسال كل شيء (التدقيق الكامل للتطبيق الخاص بك).
ولكن فقط إذا كان المستخدم يريد ذلك ("ردود الفعل" زر) أو إذا كان هناك استثناء صريح، خطأ فادح، حالة المشكلة في التطبيق.

استخدمنا كل من خدمات الويب والبريد الإلكتروني (SMTPClient). أفكاري على هذه

خدمة ويب
جيد

  • لا تكوين خاص لكل مستخدم
  • حد الحجم، أكثر من 5MB-8MB من البريد الإلكتروني ممكن

سيئة

  • مرئية عامة (مثل القراصنة للعب مع هذه الأشياء)
  • تطوير إضافي لإنشاء خدمة الويب مع نهاية ظهر DB
  • إنشاء حقول إضافية في وقت لاحق سيء
  • التغييرات في خدمة الويب ليست جيدة!

SMTPClient.
جيد

  • لا تكوين خاص لكل مستخدم
  • تسجيل الدخول إلى المجلد العمومي يجعل البحث / تصفية سهلة (تجميع، ...)
  • جميع البيانات الممكنة لإرسال، لقطات الشاشة، Stacktrace، إعدادات المستخدم، ...
    -> HTML
  • التغييرات في تنسيق التسجيل والمعلومات أمر سهل، لأننا استخدمنا رسائل البريد الإلكتروني HTML

سيئة

  • التكوين الخاص لكل مستخدم (خادم SMTP، مستخدم البريد الإلكتروني، ...)
  • حجم الحد من البريد الإلكتروني (5MB-8MB ؟؟)
  • تسجيل الدخول إلى DB من رسائل البريد الإلكتروني يتطلب الكثير من التطوير

يمكنك كتابة ذلك بنفسك، أو يمكنك استخدام شيء مثل log4net., ، يعتني بتسجيل الاستثناء لك ...

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

على جانب العميل / المرسل، أعتقد أن العرض المنبثق لإرسال السجلات هي فكرة جيدة. إذا كان Windows، يمكنك استخدام MAPI لإرسال البريد الإلكتروني. على مشكلة "البريد" نظام UNIX يعمل على معظم الأنظمة.

يمكنك مطالبة المستخدم بعنوان بريد إلكتروني في رسالة التأكيد، وربما تقدم بعض الخيارات حول كيفية إرسالها (بما في ذلك نسخ / لصق في عميل البريد الخاص باختيارهم).

شيء واحد يجب عليك ليس هل ترسل المعلومات دون إذن المستخدم.

إذا كنت لا تتوقع إرسال العديد من التقارير في يوم واحد ... يمكنك إنشاء حساب Gmail واستخدام ذلك لإرسال رسائل البريد الإلكتروني للتحصل على الاضطرار إلى إجبار المستخدم على تكوين خادم SMTP. لست متأكدا من شروط وأحكام Gmail للقيام بذلك.

فيما يلي فئة كتبتها التي ترسل رسالة بريد إلكتروني باستخدام حساب Gmail ...

من الواضح أن هناك بعض المشكلات الأمنية هنا مثل شخص يمكن أن يحتمل الوصول إلى حساب Gmail الخاص بك. إذن خذ هذا بعين الاعتبار.

هناك طرق في هذه الفئة لإرسال البريد الإلكتروني بشكل متزامن أو غير متزامن.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Collections;
using System.Text;
using System.Net;
using System.Net.Mail;
using System.Net.Mime; 
//Mime is Not necerrary if you dont change the msgview and 
//if you dont add custom/extra headers 
using System.Threading;
using System.IO;
using System.Windows.Forms; // needed for MessageBox only.



namespace BR.Util
{
    public class Gmailer
    {

        SmtpClient client = new SmtpClient();
        static String mDefaultToAddress = "yourToAddress@yourdomain.com";
        static String mDefaultFromAddress = "anonymous@gmail.com";
        static String mDefaultFromDisplayName = "Anonymous";

        String mGmailLogin = "someaccount@gmail.com";
        String mGmailPassword = "yourpassword";


        public Gmailer()
        {
            client.Credentials = new System.Net.NetworkCredential(mGmailLogin, mGmailPassword);
            client.Port = 587;           
            client.Host = "smtp.gmail.com";
            client.EnableSsl = true;
            client.SendCompleted += new SendCompletedEventHandler(Gmailer_DefaultAsyncSendCompletedHandler);
        }

        public void setSendCompletedHandler(SendCompletedEventHandler pHandler)
        {
            client.SendCompleted -= Gmailer_DefaultAsyncSendCompletedHandler;
            client.SendCompleted += pHandler;
        }

        /// <summary>
        /// Static method which sends an email synchronously.
        /// It uses a hardcoded from email.
        /// </summary>
        /// <returns></returns>
        public static bool quickSend(String toEmailAddress, String subject, String body)
        {
            return Gmailer.quickSend(toEmailAddress, mDefaultFromAddress, mDefaultFromDisplayName, subject, body);
        }

        /// <summary>
        /// Static method which sends an email synchronously.
        /// It uses the hardcoded email address.
        /// </summary>
        /// <returns>true if successful, false if an error occurred.</returns>
        public static bool quickSend(String toEmailAddress, String fromEmailAddress,
                                     String fromDisplayName, String subject, String body)
        {
            try
            {
                Gmailer gmailer = new Gmailer();
                System.Net.Mail.MailMessage mailMsg = gmailer.createMailMessage(toEmailAddress, fromEmailAddress, fromDisplayName, subject, body);
                gmailer.send(mailMsg);
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        // <summary> creates a MailMessage object initialized with the default values.</summary>
        public System.Net.Mail.MailMessage createMailMessage()
        {
            return createMailMessage(mDefaultToAddress, mDefaultFromAddress, mDefaultFromDisplayName, mDefaultEmailSubject, mDefaultEmailBody);
        }

        public System.Net.Mail.MailMessage createMailMessage(String toEmailAddress, String fromEmailAddress, 
                                                             String fromDisplayName, String subject, String body)
        {
            //Build The MSG
            System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
            msg.To.Add(toEmailAddress);
            msg.From = new MailAddress(fromEmailAddress, fromDisplayName, System.Text.Encoding.UTF8);
            msg.Subject = subject;
            msg.SubjectEncoding = System.Text.Encoding.UTF8;
            msg.Body = body;
            msg.BodyEncoding = System.Text.Encoding.UTF8;
            msg.IsBodyHtml = false;
            msg.Priority = MailPriority.High;
            return msg;
        }

        public System.Net.Mail.MailMessage addAttachmentToMailMessage(System.Net.Mail.MailMessage msg, String attachmentPath)
        {
            msg.Attachments.Add(new Attachment(attachmentPath));
            return msg;
        }

        // <summary> method which blocks until the MailMessage has been sent.  Throws
        // System.Net.Mail.SmtpException if error occurs.</summary>
        public void send(System.Net.Mail.MailMessage pMailMessage)
        {
            //try {
                client.Send(pMailMessage);
            //}
            //catch (System.Net.Mail.SmtpException ex)
            //{
            //    MessageBox.Show(ex.Message, "Send Mail Error");
            //}
        }

        // 
        public void sendAsync(System.Net.Mail.MailMessage pMailMessage)
        {
            object userState = pMailMessage;
            try
            {
                MailSent = false;
                client.SendAsync(pMailMessage, userState);
            }
            catch (System.Net.Mail.SmtpException ex)
            {
                MessageBox.Show(ex.Message, "Send Mail Error");
            }
        }

        // <summary> 
        // Provides a default SendComplete handler which is activated when an AsyncCompletedEvent 
        // is triggered by the private client variable.  This is useful for debugging etc.
        // Use the method setSendCompletedHandler to define your own application specific handler.
        // That method also turns this handler off.
        // </summary>
        public void Gmailer_DefaultAsyncSendCompletedHandler(object sender, AsyncCompletedEventArgs e)
        {
            MailMessage mail = (MailMessage)e.UserState;
            string subject = mail.Subject;

            if (e.Cancelled)
            {
                string cancelled = string.Format("[{0}] Send canceled.", subject);
                MessageBox.Show(cancelled);                
            }
            if (e.Error != null)
            {
                string error = String.Format("[{0}] {1}", subject, e.Error.ToString());
                MessageBox.Show(error);                
            }
            else
            {
                MessageBox.Show("Message sent.");
            }
            MailSent = true;
        }


        private bool _MailSent = false;
        /// <summary>
        /// Set to false when an async send operation is started and is set to true when finished.
        /// </summary>
        public bool MailSent
        {
            set
            {
                _MailSent = value;
            }
            get
            {
                return _MailSent;
            }
        }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top