Beispiel #1
0
        /// <summary>
        /// Reports an administrator-correctable fault (a problem that could later cause errors) to the administrators.
        /// </summary>
        public static void ReportAdministratorCorrectableFault(string message)
        {
            var emailMessage = getFaultEmailMessage(message);

            emailMessage.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses());
            EmailStatics.SendEmailWithDefaultFromAddress(emailMessage);
        }
Beispiel #2
0
        /// <summary>
        /// Reports an administrator-correctable error to the administrators.
        /// </summary>
        public static void ReportAdministratorCorrectableError(Exception e)
        {
            var emailMessage = getErrorEmailMessage(e.Message);

            emailMessage.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses());
            EmailStatics.SendEmailWithDefaultFromAddress(emailMessage);
        }
Beispiel #3
0
        protected override void loadData()
        {
            ph.AddControlsReturnThis(new LegacyParagraph("You may report any problems, make suggestions, or ask for help here."));

            FormState.ExecuteWithDataModificationsAndDefaultAction(
                PostBack.CreateFull(firstModificationMethod: modifyData, actionGetter: () => new PostBackAction(new ExternalResourceInfo(info.ReturnUrl)))
                .ToCollection(),
                () => {
                var list = FormItemList.CreateStack();
                list.AddFormItems(
                    new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName).ToMailAddress()
                    .ToString()
                    .ToComponents()
                    .ToFormItem(label: "From".ToComponents()),
                    "{0} ({1} for this system)".FormatWith(
                        StringTools.GetEnglishListPhrase(EmailStatics.GetAdministratorEmailAddresses().Select(i => i.DisplayName), true),
                        "support contacts".ToQuantity(EmailStatics.GetAdministratorEmailAddresses().Count(), showQuantityAs: ShowQuantityAs.None))
                    .ToComponents()
                    .ToFormItem(label: "To".ToComponents()),
                    body.ToTextControl(false, setup: TextControlSetup.Create(numberOfRows: 10), value: "").ToFormItem(label: "Message".ToComponents()));
                ph.AddControlsReturnThis(list.ToCollection().GetControls());

                EwfUiStatics.SetContentFootActions(new ButtonSetup("Send Message").ToCollection());
            });
        }
Beispiel #4
0
        /// <summary>
        /// Sends a notification to the administrators. Do not use for anything that requires corrective action.
        /// </summary>
        public static void SendAdministratorNotification(string message)
        {
            var emailMessage = getNotificationEmailMessage(message);

            emailMessage.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses());
            EmailStatics.SendEmailWithDefaultFromAddress(emailMessage);
        }
        protected override void loadData()
        {
            ph.AddControlsReturnThis(new LegacyParagraph("You may report any problems, make suggestions, or ask for help here."));

            var pb = PostBack.CreateFull(firstModificationMethod: modifyData, actionGetter: () => new PostBackAction(new ExternalResourceInfo(info.ReturnUrl)));

            FormState.ExecuteWithDataModificationsAndDefaultAction(
                pb.ToCollection(),
                () => {
                var table = FormItemBlock.CreateFormItemTable();
                table.AddFormItems(
                    FormItem.Create(
                        "From",
                        new PlaceHolder().AddControlsReturnThis(
                            new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName).ToMailAddress().ToString().ToComponents().GetControls())),
                    FormItem.Create(
                        "To",
                        new PlaceHolder().AddControlsReturnThis(
                            "{0} ({1} for this system)".FormatWith(
                                StringTools.GetEnglishListPhrase(EmailStatics.GetAdministratorEmailAddresses().Select(i => i.DisplayName), true),
                                "support contacts".ToQuantity(EmailStatics.GetAdministratorEmailAddresses().Count(), showQuantityAs: ShowQuantityAs.None))
                            .ToComponents()
                            .GetControls())),
                    FormItem.Create(
                        "Message",
                        new EwfTextBox("", rows: 10),
                        validationGetter:
                        control =>
                        new EwfValidation(
                            (pbv, validator) => body.Value = validator.GetString(new ValidationErrorHandler("message"), control.GetPostBackValue(pbv), false))));
                ph.AddControlsReturnThis(table);
            });

            EwfUiStatics.SetContentFootActions(new ActionButtonSetup("Send Message", new PostBackButton(pb)));
        }
        private void tick(object state)
        {
            TelemetryStatics.ExecuteBlockWithStandardExceptionHandling(
                () => {
                // We need to schedule the next tick even if there is an exception thrown in this one. Use try-finally instead of CallEveryMethod so we don't lose
                // exception stack traces.
                try {
                    var currentInstant = SystemClock.Instance.GetCurrentInstant();
                    var interval       = new TickInterval(new Interval(lastTickInstant, currentInstant));
                    lastTickInstant    = currentInstant;

                    if (ConfigurationStatics.IsLiveInstallation && interval.FitsPattern(OperationRecurrencePattern.CreateDaily(0, 0)))
                    {
                        EmailStatics.SendHealthCheckEmail(WindowsServiceMethods.GetServiceInstalledName(service));
                    }

                    service.Tick(interval);
                }
                finally {
                    try {
                        timer.Change(tickInterval, Timeout.Infinite);
                    }
                    catch (ObjectDisposedException) {
                        // This should not be necessary with the Timer.Dispose overload we are using, but see http://stackoverflow.com/q/12354883/35349.
                    }
                }
            });
        }
        private void tick(object state)
        {
            TelemetryStatics.ExecuteBlockWithStandardExceptionHandling(
                () => {
                // We need to schedule the next tick even if there is an exception thrown in this one. Use try-finally instead of CallEveryMethod so we don't lose
                // exception stack traces.
                try {
                    var now = DateTime.Now;
                    if (ConfigurationStatics.IsLiveInstallation && !ConfigurationStatics.MachineIsStandbyServer &&
                        new[] { lastHealthCheckDateAndTime, now }.Any(dt => dt.Date.IsBetweenDateTimes(lastHealthCheckDateAndTime, now)))
                    {
                        EmailStatics.SendHealthCheckEmail(WindowsServiceMethods.GetServiceInstalledName(service));
                    }
                    lastHealthCheckDateAndTime = now;

                    service.Tick();
                }
                finally {
                    try {
                        timer.Change(tickInterval, Timeout.Infinite);
                    }
                    catch (ObjectDisposedException) {
                        // This should not be necessary with the Timer.Dispose overload we are using, but see http://stackoverflow.com/q/12354883/35349.
                    }
                }
            });
        }
        /// <summary>
        /// After setting the From property to the from address specified in the config file, sends the specified mail message using the SMTP server specified in
        /// the config file.
        /// </summary>
        public static void SendEmailWithDefaultFromAddress(EmailMessage m)
        {
            assertClassInitialized();

            m.From = new EmailAddress(
                ConfigurationStatics.SystemGeneralProvider.EmailDefaultFromAddress,
                ConfigurationStatics.SystemGeneralProvider.EmailDefaultFromName);
            EmailStatics.SendEmail(m);
        }
        private void modifyData()
        {
            var message = new EmailMessage
            {
                Subject  = "Contact from " + AppTools.SystemName,
                BodyHtml = ("Contact from " + AppTools.User.Email + Environment.NewLine + Environment.NewLine + emailText).GetTextAsEncodedHtml()
            };

            message.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses());
            message.ReplyToAddresses.Add(new EmailAddress(AppTools.User.Email));
            EmailStatics.SendEmailWithDefaultFromAddress(message);
            AddStatusMessage(StatusMessageType.Info, "Your feedback has been sent.");
        }
        internal static void SendPassword(string emailAddress, string password)
        {
            string subject;
            string bodyHtml;

            SystemProvider.GetPasswordResetParams(emailAddress, password, out subject, out bodyHtml);
            var m = new EmailMessage {
                Subject = subject, BodyHtml = bodyHtml
            };

            m.ToAddresses.Add(new EmailAddress(emailAddress));
            EmailStatics.SendEmailWithDefaultFromAddress(m);
        }
Beispiel #11
0
        private void modifyData()
        {
            var message = new EmailMessage
            {
                From     = new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName),
                Subject  = "Contact from " + ConfigurationStatics.SystemName,
                BodyHtml = body.Value.GetTextAsEncodedHtml()
            };

            message.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses());
            EmailStatics.SendEmail(message);
            AddStatusMessage(StatusMessageType.Info, "Your message has been sent.");
        }
        internal static void SendHealthCheckEmail(string appFullName)
        {
            var message = new EmailMessage();

            var body           = new StringBuilder();
            var tenGibibytes   = 10 * Math.Pow(1024, 3);
            var freeSpaceIsLow = false;

            foreach (var driveInfo in DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.Fixed))
            {
                var bytesFree = driveInfo.TotalFreeSpace;
                freeSpaceIsLow = freeSpaceIsLow || bytesFree < tenGibibytes;
                body.AppendLine("{0} free on {1} drive.".FormatWith(FormattingMethods.GetFormattedBytes(bytesFree), driveInfo.Name));
            }

            message.Subject  = StringTools.ConcatenateWithDelimiter(" ", "Health check", freeSpaceIsLow ? "and WARNING" : "", "from " + appFullName);
            message.BodyHtml = body.ToString().GetTextAsEncodedHtml();
            EmailStatics.SendDeveloperNotificationEmail(message);
        }
        protected override PageContent getContent()
        {
            var body = new DataValue <string>();

            return(FormState.ExecuteWithDataModificationsAndDefaultAction(
                       PostBack.CreateFull(
                           modificationMethod: () => {
                var message = new EmailMessage
                {
                    Subject = "Support request from {0} in {1}".FormatWith(
                        AppTools.User.FriendlyName.Any() ? AppTools.User.FriendlyName : AppTools.User.Email,
                        ConfigurationStatics.SystemDisplayName),
                    BodyHtml = body.Value.GetTextAsEncodedHtml()
                };
                message.ReplyToAddresses.Add(new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName));
                message.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses());
                EmailStatics.SendEmailWithDefaultFromAddress(message);
                AddStatusMessage(StatusMessageType.Info, "Your message has been sent.");
            },
                           actionGetter: () => new PostBackAction(new ExternalResource(ReturnUrl)))
                       .ToCollection(),
                       () => new UiPageContent(contentFootActions: new ButtonSetup("Send Message").ToCollection())
                       .Add(new Paragraph("You may report any problems, make suggestions, or ask for help here.".ToComponents()))
                       .Add(
                           FormItemList.CreateStack(
                               items: new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName).ToMailAddress()
                               .ToString()
                               .ToComponents()
                               .ToFormItem(label: "From".ToComponents())
                               .Append(
                                   "{0} ({1} for this system)".FormatWith(
                                       StringTools.GetEnglishListPhrase(EmailStatics.GetAdministratorEmailAddresses().Select(i => i.DisplayName), true),
                                       "support contacts".ToQuantity(EmailStatics.GetAdministratorEmailAddresses().Count(), showQuantityAs: ShowQuantityAs.None))
                                   .ToComponents()
                                   .ToFormItem(label: "To".ToComponents()))
                               .Append(
                                   body.ToTextControl(false, setup: TextControlSetup.Create(numberOfRows: 10), value: "").ToFormItem(label: "Message".ToComponents()))
                               .Materialize()))));
        }
Beispiel #14
0
        /// <summary>
        /// Initializes the system. This includes loading application settings from the configuration file. The application name should be scoped within the system.
        /// For non web applications, this method must be called directly from the main executable assembly and not from a supporting library.
        ///
        /// To debug this method, create a folder called C:\AnyoneFullControl and give Everyone full control. A file will appear in that folder explaining how far
        /// it got in init.
        /// </summary>
        /// <param name="globalInitializer">The system's global initializer. Do not pass null.</param>
        /// <param name="appName"></param>
        /// <param name="isClientSideApp"></param>
        /// <param name="assemblyFolderPath">Pass a nonempty string to override the assembly folder path, which is used to locate the installation folder. Use with
        /// caution.</param>
        /// <param name="mainDataAccessStateGetter">A method that returns the current main data-access state whenever it is requested, including during this
        /// InitStatics call. Do not allow multiple threads to use the same state at the same time. If you pass null, the data-access subsystem will not be
        /// available in the application.</param>
        /// <param name="useLongDatabaseTimeouts">Pass true if the application is a background process that can tolerate slow database access.</param>
        public static void InitStatics(
            SystemInitializer globalInitializer, string appName, bool isClientSideApp, string assemblyFolderPath = "",
            Func <DataAccessState> mainDataAccessStateGetter = null, bool useLongDatabaseTimeouts = false)
        {
            var initializationLog = "Starting init";

            try {
                if (initialized)
                {
                    throw new ApplicationException("This class can only be initialized once.");
                }

                if (globalInitializer == null)
                {
                    throw new ApplicationException("The system must have a global initializer.");
                }

                // Initialize these before the exception handling block below because it's reasonable for the exception handling to depend on them.
                ConfigurationStatics.Init(assemblyFolderPath, globalInitializer.GetType(), appName, isClientSideApp, ref initializationLog);
                EmailStatics.Init();
                TelemetryStatics.Init();

                // Setting the initialized flag to true must be done before executing the secondary init block below so that exception handling works.
                initialized        = true;
                initializationLog += Environment.NewLine + "Succeeded in primary init.";
            }
            catch (Exception e) {
                initializationLog += Environment.NewLine + e;
                EwlStatics.EmergencyLog("Initialization log", initializationLog);
                throw;
            }

            try {
                CultureInfo.DefaultThreadCurrentCulture = Cultures.EnglishUnitedStates;

                var asposePdfLicensePath = EwlStatics.CombinePaths(ConfigurationStatics.InstallationConfiguration.AsposeLicenseFolderPath, "Aspose.PDF.lic");
                if (File.Exists(asposePdfLicensePath))
                {
                    new Aspose.Pdf.License().SetLicense(asposePdfLicensePath);
                }
                var asposeWordsLicensePath = EwlStatics.CombinePaths(ConfigurationStatics.InstallationConfiguration.AsposeLicenseFolderPath, "Aspose.Words.lic");
                if (File.Exists(asposeWordsLicensePath))
                {
                    new Aspose.Words.License().SetLicense(asposeWordsLicensePath);
                }

                AppMemoryCache.Init();
                BlobStorageStatics.Init();
                DataAccessStatics.Init();
                DataAccessState.Init(mainDataAccessStateGetter, useLongDatabaseTimeouts);
                EncryptionOps.Init();
                HtmlBlockStatics.Init();
                UserManagementStatics.Init();

                GlobalInitializationOps.globalInitializer = globalInitializer;
                globalInitializer.InitStatics();
            }
            catch (Exception e) {
                secondaryInitFailed = true;

                // Suppress all exceptions since they would prevent apps from knowing that primary initialization succeeded. EWF apps need to know this in order to
                // automatically restart themselves. Other apps could find this knowledge useful as well.
                try {
                    TelemetryStatics.ReportError("An exception occurred during application initialization:", e);
                }
                catch {}
            }
        }
Beispiel #15
0
 public static void SendEmailWithDefaultFromAddress(EmailMessage m)
 {
     assertClassInitialized();
     EmailStatics.SendEmailWithDefaultFromAddress(m);
 }
Beispiel #16
0
 /// <summary>
 /// Standard library use only.
 /// </summary>
 public void SendHealthCheck()
 {
     EmailStatics.SendHealthCheckEmail(ConfigurationStatics.InstallationConfiguration.FullShortName + " - " + ConfigurationStatics.AppName);
 }
Beispiel #17
0
        /// <summary>
        /// Reports an error to the developers. The report includes the specified exception and additional information about the running program. The prefix
        /// provides additional information before the standard exception and page information.
        /// </summary>
        public static void ReportError(string prefix, Exception exception)
        {
            using (var sw = new StringWriter()) {
                if (prefix.Length > 0)
                {
                    sw.WriteLine(prefix);
                    sw.WriteLine();
                }
                if (exception != null)
                {
                    sw.WriteLine(exception.ToString());
                    sw.WriteLine();
                }

                sw.WriteLine("Application: {0}".FormatWith(ConfigurationStatics.AppName));
                sw.WriteLine("Version: {0}".FormatWith(ConfigurationStatics.AppAssembly.GetName().Version));

                if (!ConfigurationStatics.IsDevelopmentInstallation)
                {
                    sw.WriteLine();
                    sw.WriteLine("Installation: {0}".FormatWith(ConfigurationStatics.InstallationConfiguration.InstallationName));
                    sw.WriteLine("Machine: {0}".FormatWith(Tewl.Tools.NetTools.GetLocalHostName()));
                }

                if (NetTools.IsWebApp())
                {
                    // This check ensures that there is an actual request, which is not the case during application initialization.
                    if (EwfApp.Instance != null && EwfApp.Instance.RequestState != null)
                    {
                        sw.WriteLine();
                        sw.WriteLine("URL: " + AppRequestState.Instance.Url);

                        sw.WriteLine();
                        foreach (string fieldName in HttpContext.Current.Request.Form)
                        {
                            sw.WriteLine("Form field " + fieldName + ": " + HttpContext.Current.Request.Form[fieldName]);
                        }

                        sw.WriteLine();
                        foreach (string cookieName in HttpContext.Current.Request.Cookies)
                        {
                            sw.WriteLine("Cookie " + cookieName + ": " + HttpContext.Current.Request.Cookies[cookieName].Value);
                        }

                        sw.WriteLine();
                        sw.WriteLine("User agent: " + HttpContext.Current.Request.GetUserAgent());
                        sw.WriteLine("Referrer: " + NetTools.ReferringUrl);

                        User user         = null;
                        User impersonator = null;

                        // exception-prone code
                        try {
                            user         = AppTools.User;
                            impersonator = AppRequestState.Instance.ImpersonatorExists ? AppRequestState.Instance.ImpersonatorUser : null;
                        }
                        catch {}

                        if (user != null)
                        {
                            sw.WriteLine("User: {0}{1}".FormatWith(user.Email, impersonator != null ? " (impersonated by {0})".FormatWith(impersonator.Email) : ""));
                        }
                    }
                }

                EwlStatics.CallEveryMethod(
                    () => {
                    lock ( errorEmailLimiter ) {
                        errorEmailLimiter.RequestAction(
                            () => EmailStatics.SendDeveloperNotificationEmail(getErrorEmailMessage(sw.ToString())),
                            () => SendDeveloperNotification(
                                "An error occurred and the email rate-limit was reached! See the log file for this and any other errors that may occur in the near future."),
                            () => {});
                    }
                },
                    () => logError(sw.ToString()));
            }
        }
Beispiel #18
0
        /// <summary>
        /// Reports an error to the developers. The report includes the specified exception and additional information about the running program. The prefix
        /// provides additional information before the standard exception and page information.
        /// </summary>
        public static void ReportError(string prefix, Exception exception)
        {
            using (var sw = new StringWriter()) {
                if (prefix.Length > 0)
                {
                    sw.WriteLine(prefix);
                    sw.WriteLine();
                }
                if (exception != null)
                {
                    sw.WriteLine(exception.ToString());
                    sw.WriteLine();
                }

                if (NetTools.IsWebApp())
                {
                    // This check ensures that there is an actual request, which is not the case during application initialization.
                    if (EwfApp.Instance != null && EwfApp.Instance.RequestState != null)
                    {
                        sw.WriteLine("URL: " + AppRequestState.Instance.Url);

                        sw.WriteLine();
                        foreach (string fieldName in HttpContext.Current.Request.Form)
                        {
                            sw.WriteLine("Form field " + fieldName + ": " + HttpContext.Current.Request.Form[fieldName]);
                        }

                        sw.WriteLine();
                        foreach (string cookieName in HttpContext.Current.Request.Cookies)
                        {
                            sw.WriteLine("Cookie " + cookieName + ": " + HttpContext.Current.Request.Cookies[cookieName].Value);
                        }

                        sw.WriteLine();
                        sw.WriteLine("User agent: " + HttpContext.Current.Request.GetUserAgent());
                        sw.WriteLine("Referrer: " + NetTools.ReferringUrl);

                        User user         = null;
                        User impersonator = null;

                        // exception-prone code
                        try {
                            user         = AppTools.User;
                            impersonator = AppRequestState.Instance.ImpersonatorExists ? AppRequestState.Instance.ImpersonatorUser : null;
                        }
                        catch {}

                        if (user != null)
                        {
                            sw.WriteLine("User: {0}{1}".FormatWith(user.Email, impersonator != null ? " (impersonated by {0})".FormatWith(impersonator.Email) : ""));
                        }
                    }
                }
                else
                {
                    sw.WriteLine("Program: " + ConfigurationStatics.AppName);
                    sw.WriteLine("Version: " + ConfigurationStatics.AppAssembly.GetName().Version);
                    sw.WriteLine("Machine: " + StandardLibraryMethods.GetLocalHostName());
                }

                StandardLibraryMethods.CallEveryMethod(
                    delegate { EmailStatics.SendDeveloperNotificationEmail(getErrorEmailMessage(sw.ToString())); },
                    delegate { logError(sw.ToString()); });
            }
        }
        /// <summary>
        /// Initializes the system. This includes loading application settings from the configuration file. The application name should be scoped within the system.
        /// For non web applications, this method must be called directly from the main executable assembly and not from a supporting library.
        ///
        /// To debug this method, create a folder called C:\AnyoneFullControl and give Everyone full control. A file will appear in that folder explaining how far
        /// it got in init.
        /// </summary>
        /// <param name="globalInitializer">The system's global initializer. Do not pass null.</param>
        /// <param name="appName"></param>
        /// <param name="isClientSideProgram"></param>
        /// <param name="useRelativeInstallationPath">Pass true to use a relative path for the installation folder. This means that the folder will be located using
        /// the working directory rather than the assembly path. Use with caution.</param>
        /// <param name="mainDataAccessStateGetter">A method that returns the current main data-access state whenever it is requested, including during this
        /// InitStatics call. Do not allow multiple threads to use the same state at the same time. If you pass null, the data-access subsystem will not be
        /// available in the application.</param>
        public static void InitStatics(
            SystemInitializer globalInitializer, string appName, bool isClientSideProgram, bool useRelativeInstallationPath = false,
            Func <DataAccessState> mainDataAccessStateGetter = null)
        {
            var initializationLog = "Starting init";

            try {
                if (initialized)
                {
                    throw new ApplicationException("This class can only be initialized once.");
                }

                if (globalInitializer == null)
                {
                    throw new ApplicationException("The system must have a global initializer.");
                }

                // Initialize ConfigurationStatics, including the general provider, before the exception handling block below because it's reasonable for the exception
                // handling to depend on this.
                ConfigurationStatics.Init(useRelativeInstallationPath, globalInitializer.GetType(), appName, isClientSideProgram, ref initializationLog);

                // Setting the initialized flag to true must be done before executing the secondary init block below so that exception handling works.
                initialized        = true;
                initializationLog += Environment.NewLine + "Succeeded in primary init.";
            }
            catch (Exception e) {
                initializationLog += Environment.NewLine + e;
                EwlStatics.EmergencyLog("Initialization log", initializationLog);
                throw;
            }

            try {
                var asposeLicense = ConfigurationStatics.SystemGeneralProvider.AsposeLicenseName;
                if (asposeLicense.Any())
                {
                    new Aspose.Pdf.License().SetLicense(asposeLicense);
                    new Aspose.Words.License().SetLicense(asposeLicense);
                }

                AppMemoryCache.Init();
                BlobFileOps.Init();
                DataAccessStatics.Init();
                DataAccessState.Init(mainDataAccessStateGetter);
                EmailStatics.Init();
                EncryptionOps.Init();
                HtmlBlockStatics.Init();
                InstallationSupportUtility.ConfigurationLogic.Init1();
                UserManagementStatics.Init();

                GlobalInitializationOps.globalInitializer = globalInitializer;
                globalInitializer.InitStatics();
            }
            catch (Exception e) {
                secondaryInitFailed = true;

                // Suppress all exceptions since they would prevent apps from knowing that primary initialization succeeded. EWF apps need to know this in order to
                // automatically restart themselves. Other apps could find this knowledge useful as well.
                try {
                    TelemetryStatics.ReportError("An exception occurred during application initialization:", e);
                }
                catch {}
            }
        }
Beispiel #20
0
 /// <summary>
 /// Sends a notification to the developers. Do not use for anything that requires corrective action.
 /// </summary>
 public static void SendDeveloperNotification(string message)
 {
     EmailStatics.SendDeveloperNotificationEmail(getNotificationEmailMessage(message));
 }
Beispiel #21
0
 /// <summary>
 /// Reports a fault (a problem that could later cause errors) to the developers.
 /// </summary>
 public static void ReportFault(string message)
 {
     EmailStatics.SendDeveloperNotificationEmail(getFaultEmailMessage(message));
 }
 public static void SendEmail(EmailMessage message)
 {
     assertClassInitialized();
     EmailStatics.SendEmail(message);
 }