Asp.net mvc MVC自定义错误记录器试图使用异步调用web api

Asp.net mvc MVC自定义错误记录器试图使用异步调用web api,asp.net-mvc,error-handling,Asp.net Mvc,Error Handling,MVC自定义错误记录器使用异步调用web api 我有一个自定义错误记录器,我想: 将文本文件写入文件夹 使用web api,向工作人员发送警报电子邮件,以通知错误已写入文件夹 最后,显示相应的错误视图 #在我引入“OneException”方法代码来处理#2之前,1和#3工作得很好。为此,我必须在调用具有该特性的web api时向该方法添加“async” 现在,当MVC检测到一个代码错误时,它会转到自定义错误记录器,但会失败,因为它不喜欢该方法上的“异步” 我得到: An asynchrono

MVC自定义错误记录器使用异步调用web api

我有一个自定义错误记录器,我想:

  • 将文本文件写入文件夹
  • 使用web api,向工作人员发送警报电子邮件,以通知错误已写入文件夹
  • 最后,显示相应的错误视图
  • #在我引入“OneException”方法代码来处理#2之前,1和#3工作得很好。为此,我必须在调用具有该特性的web api时向该方法添加“async”

    现在,当MVC检测到一个代码错误时,它会转到自定义错误记录器,但会失败,因为它不喜欢该方法上的“异步”

    我得到:

    An asynchronous operation cannot be started at this time. Asynchronous operations may only be started 
    within an asynchronous handler or module or during certain events in the Page lifecycle. If this 
    exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>. 
    This exception may also indicate an attempt to call an "async void" method, which is generally 
    unsupported within ASP.NET request processing. Instead, the asynchronous method should return a Task, 
    and the caller should await it.
    
    但是你可以得到:

     'ErrorLoggerAttribute.OnException[ExceptionContext]': return type must be 
      void to match overridden member 
      'HandleErrorAttribute.OnException(ExceptionContext)'.
    

    当我想调用web api来发送警报电子邮件时,如何解决这个问题


    在FilterConfig.cs中,ErrorLoggerAttribute指向一个自定义错误记录器:

    filters.Add(new ErrorLoggerAttribute());
    
    以下是自定义ErrorLoggerAttribute.cs:

        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // An async override method.
        // - Fired off on exception.
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        public async override void OnException(ExceptionContext filterContext)
        {
            //#############################################################################################
            // Write a text file to the ClientErrorLog folder.
            // - It may append to the text file if it already exists.
            //#############################################################################################
    
            string strLogText = "";
            Exception ex = filterContext.Exception;
            filterContext.ExceptionHandled = true;
            var objClass = filterContext;
    
            // Set the text.
            strLogText += "Message ---\n{0}" + ex.Message;
    
            // Check the error source.
            if (ex.Source == ".Net SqlClient Data Provider")
            {
                strLogText += Environment.NewLine + "SqlClient Error ---\n{0}" + "Check Sql Error";
            }
            else if (ex.Source == "System.Web.Mvc")
            {
                strLogText += Environment.NewLine + ".Net Error ---\n{0}" + "Check MVC Code For Error";
            }
            else if (filterContext.HttpContext.Request.IsAjaxRequest() == true)
            {
                strLogText += Environment.NewLine + ".Net Error ---\n{0}" + "Check MVC Ajax Code For Error";
            }
    
            strLogText += Environment.NewLine + "Source ---\n{0}" + ex.Source;
            strLogText += Environment.NewLine + "StackTrace ---\n{0}" + ex.StackTrace;
            strLogText += Environment.NewLine + "TargetSite ---\n{0}" + ex.TargetSite;
    
            if (ex.InnerException != null)
            {
                // Error prone.
                strLogText += Environment.NewLine + "Inner Exception is {0}" + ex.InnerException;
            }
            if (ex.HelpLink != null)
            {
                // Error prone.
                strLogText += Environment.NewLine + "HelpLink ---\n{0}" + ex.HelpLink;
            }
    
            // The Textwriter for writing characters to a stream.
            StreamWriter log;
    
            // Set the date. 
            // - For instance: 27-October-2020
            string timestamp = DateTime.Now.ToString("d-MMMM-yyyy", new CultureInfo("en-GB"));
    
            // Read the web.config and get the error log path to write an 'error log' text file to.
            string error_folder = ConfigurationManager.AppSettings["ClientErrorLogPath"].ToString();
    
            // Check if the error folder exists.
            if (!System.IO.Directory.Exists(error_folder))
            {
                System.IO.Directory.CreateDirectory(error_folder);
            }
    
            // Check if the text file exists.
            // - For instance, looks for: ClientErrorLog\Log_27-October-2020.txt
            if (!File.Exists(String.Format(@"{0}\Log_{1}.txt", error_folder, timestamp)))
            {
                // Create the text file.
                log = new StreamWriter(String.Format(@"{0}\Log_{1}.txt", error_folder, timestamp));
            }
            else
            {
                // Set for an add(append) to the text file.
                log = File.AppendText(String.Format(@"{0}\Log_{1}.txt", error_folder, timestamp));
            }
    
            var controllerName = (string)filterContext.RouteData.Values["controller"];
            var actionName = (string)filterContext.RouteData.Values["action"];
    
            // Start writing to the 'error log' text file.
            // - First, write the timestamp to the file.
            log.WriteLine(Environment.NewLine + DateTime.Now);
    
            log.WriteLine("------------------------------------------------------------------------------------------------");
            log.WriteLine("Controller Name :- " + controllerName);
            log.WriteLine("Action Method Name :- " + actionName);
            log.WriteLine("------------------------------------------------------------------------------------------------");
    
            // Write the filter context.
            log.WriteLine(objClass);
    
            // Write the text.
            log.WriteLine(strLogText);
    
            // Write an empty line.
            log.WriteLine();
    
            //#############################################################################################
            // Using the web api, send a client error alert email to a staff member (an Admin) as to notify
            // that an error was written to the ClientErrorLog folder.
            //#############################################################################################
    
            string errorMessage = "";
            string exceptionMessage = "";
    
            try
            {
                // Instantiate the ControlResult for getting data from the web api.
                ControlResult controlResult = new ControlResult();
    
                // -----------------------------------------------------------------------------------------------------------------------------------------------
                // 1st: There is no 'user name' available here - can't reference the session variable.
                //        A 'user name' is needed so that the process functions properly - need to access the web api with a valid 'user name'.
                // -----------------------------------------------------------------------------------------------------------------------------------------------
    
                // Get the control control 'user name'.
                // - It calls a model class to execute a method.
                controlResult = await GetControl();
    
                // Check if an error occurred in the web api.
                if (controlResult.ApiErrorMessage == null)
                {
                    // Got the control 'user name' in order to access the web api'.
    
                    try
                    {
                        // -----------------------------------------------------------------------------------------------------------------------------------------------
                        // 2nd: Send a client error alert email to a staff member (an Admin) as to notify that an error was written to the 
                        //         ClientErrorLog folder.
                        // -----------------------------------------------------------------------------------------------------------------------------------------------
    
                        // Instantiate the ClientErrorResult for getting data from the web api.
                        ClientErrorResult clientErrorResult = new ClientErrorResult();
    
                        // Instantiate the BLL_Client class so that the functions can be referenced. 
                        BLL_ClientError bll_ClientError = new BLL_ClientError();
    
                        // Call the web api to process the error.
                        // - It calls a model class to execute a method.
                        clientErrorResult = await bll_ClientError.ProcessClientErrorNoLog(controlResult.UserName);
    
                        // Check if an error occurred in the web api.
                        if (clientErrorResult.ApiErrorMessage != null)
                        {
                            // Set the error message with the web api error message. The ReasonPhrase set in BLL_ClientError.
                            errorMessage = controlResult.ApiErrorMessage;
                        }
                    }
                    catch (Exception ex3)
                    {
                        // Friendly user message.
                        errorMessage = "Server error on sending a client error alert. Exception error: " + ex3.Message;
                    }
                }
                else
                {
                    // Set the error message with the web api error message. The ReasonPhrase set in BLL_Control.
                    errorMessage = controlResult.ApiErrorMessage;
                }
            }
            catch (Exception ex1)
            {
                // Friendly user message.
                exceptionMessage = "Server error on getting. Exception error: " + ex1.Message;
    
                try
                {
                    // Instantiate the ClientErrorResult for getting data from the web api.
                    ClientErrorResult clientErrorResult = new ClientErrorResult();
    
                    // Call the web api to process the error.
                    // Note: the 'user name' being passed. Using 'Control' as a 'user name' is not available.
                    // - It calls a model class to execute a method.
                    clientErrorResult = await ProcessClientError("Control", ex1.Message, "Server error on getting the control field. Method: OnException");
    
                    // Check if an error occurred in the web api.
                    if (clientErrorResult.ApiErrorMessage == null)
                    {
                        // All good. Just show the friendly user message set above.
                        // Pass data from the controller to the corresponding view.
                        errorMessage = exceptionMessage;
                    }
                    else
                    {
                        // Set the error message with the web api error message. The ReasonPhrase set in BLL_ClientError.
                        errorMessage = clientErrorResult.ApiErrorMessage;
                    }
                }
                catch (Exception ex2)
                {
                    // Pass data from the controller to the corresponding view.
                    errorMessage = "Failure in ProcessClientError. Exception error: " + ex2.Message + ". Original error: " + exceptionMessage;
                }
            }
    
            // Check if there was an error.
            if (errorMessage == "")
            {
                // Close the stream.
                log.Close();
    
                // Cancel the current session.
                filterContext.HttpContext.Session.Abandon();
    
                // Set the action result.
                filterContext.Result = new ViewResult()
                {
                    // Set the name of the view to render - the Views/Shared/Error.cshtml.
                    ViewName = "Error"
                };
            }
            else
            {
                // Write the error to the text file.
                // - It may append to the text file if it already exists.
    
                // Write to the 'error log' text file.
                // First, write the timestamp to the file.
                log.WriteLine(Environment.NewLine + DateTime.Now);
    
                // Set the text with a header statement.
                strLogText = "Attmpted to send a client error alert email to a staff member (an Admin) - but got an error. See it below.";
    
                // Write the text.
                log.WriteLine(strLogText);
    
                // Write an empty line.
                log.WriteLine();
    
                // Clear the previous.
                strLogText = "";
    
                // Set the text with the error message.
                strLogText += "Message ---\n{0}" + errorMessage;
    
                // Write the text.
                log.WriteLine(strLogText);
    
                // Write an empty line.
                log.WriteLine();
    
                // Close the stream.
                log.Close();
    
                // Cancel the current session.
                filterContext.HttpContext.Session.Abandon();
    
                // Set the action result.
                filterContext.Result = new ViewResult()
                {
                    // Set the name of the view to render - the Views/Shared/ErrorSendingError.cshtml.
                    ViewName = "ErrorSendingError"
                };
            }
        }
    
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // async Method.
        // Returns a model.
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        public async Task<ControlResult> GetControl()
        {
            BLL_Control bll_Control = new BLL_Control();
    
            ControlResult controlResult = new ControlResult();
    
            try
            {
                // Call the model class to get the control field.
                controlResult = await bll_Control.GetControl();
            }
            catch (Exception)
            {
                throw;
            }
    
            return controlResult;
        }
    
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // async Method.
        // Returns a model.
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        public async Task<ClientErrorResult> ProcessClientError(string userName, string errorMessage, string additionalInfo)
        {
            BLL_ClientError bll_ClientError = new BLL_ClientError();
    
            ClientErrorResult clientErrorResult = new ClientErrorResult();
    
            try
            {
                // Call the model class to process the client error.
                clientErrorResult = await bll_ClientError.ProcessClientError(userName, errorMessage, additionalInfo);
            }
            catch (Exception)
            {
                throw;
            }
    
            return clientErrorResult;
        }
    
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //异步重写方法。
    //-在异常时触发。
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    公共异步重写void OneException(ExceptionContext filterContext)
    {
    //#############################################################################################
    //将文本文件写入ClientErrorLog文件夹。
    //-如果文本文件已经存在,则可以将其附加到文本文件中。
    //#############################################################################################
    字符串strLogText=“”;
    Exception ex=filterContext.Exception;
    filterContext.ExceptionHandled=true;
    var objClass=filterContext;
    //设置文本。
    strLogText+=“消息---\n{0}”+例如消息;
    //检查错误源。
    if(ex.Source==“.Net SqlClient数据提供程序”)
    {
    strLogText+=Environment.NewLine+“SqlClient错误----\n{0}”+“检查Sql错误”;
    }
    else if(ex.Source==“System.Web.Mvc”)
    {
    strLogText+=Environment.NewLine+.Net错误----\n{0}“+“检查MVC代码是否有错误”;
    }
    else if(filterContext.HttpContext.Request.IsAjaxRequest()==true)
    {
    strLogText+=Environment.NewLine+.Net错误----\n{0}“+“检查MVC Ajax代码是否有错误”;
    }
    strLogText+=Environment.NewLine+“Source--\n{0}”+ex.Source;
    strLogText+=Environment.NewLine+“StackTrace---\n{0}”+ex.StackTrace;
    strLogText+=Environment.NewLine+“TargetSite--\n{0}”+ex.TargetSite;
    if(例如InnerException!=null)
    {
    //容易出错。
    strLogText+=Environment.NewLine+“内部异常为{0}”+ex.InnerException;
    }
    如果(例如HelpLink!=null)
    {
    //容易出错。
    strLogText+=Environment.NewLine+“HelpLink--\n{0}”+ex.HelpLink;
    }
    //用于将字符写入流的文本编写器。
    StreamWriter日志;
    //设定日期。
    //-例如:2020年10月27日
    string timestamp=DateTime.Now.ToString(“d-MMMM-yyyy”,新文化信息(“en-GB”);
    //读取web.config并获取要写入“错误日志”文本文件的错误日志路径。
    字符串错误\u folder=ConfigurationManager.AppSettings[“ClientErrorLogPath”]。ToString();
    //检查错误文件夹是否存在。
    如果(!System.IO.Directory.Exists(error_folder))
    {
    System.IO.Directory.CreateDirectory(error\u文件夹);
    }
    //检查文本文件是否存在。
    //-例如,查找:clienterorlog\Log_27-十月-2020.txt
    如果(!File.Exists(String.Format(@“{0}\Log{1}.txt”,error_folder,timestamp)))
    {
    //创建文本文件。
    log=newstreamwriter(String.Format(@{0}\log{1}.txt),error_文件夹,timestamp));
    }
    其他的
    {
    //设置为向文本文件添加(追加)。
    log=File.AppendText(String.Format(@“{0}\log{1}.txt”,error_folder,timestamp));
    }
    var controllerName=(字符串)filterContext.RouteData.Values[“controller”];
    var actionName=(字符串)filterContext.RouteData.Values[“action”];
    //开始写入“错误日志”文本文件。
    //-首先,将时间戳写入文件。
    log.WriteLine(Environment.NewLine+DateTime.Now);
    log.WriteLine(“--------------------------------------------------------------------------------------------------------------”);
    log.WriteLine(“控制器名称:-”+controllerName);
    log.WriteLine(“操作方法名称:-”+actionName);
    log.WriteLine(“--------------------------------------------------------------------------------------------------------------”);
    //编写过滤器上下文。
    log.WriteLine(对象类);
    //写课文。
    log.WriteLine(strLogText);
    //写一个空行。
    log.WriteLine();
    //#############################################################################################
    //使用web api,向工作人员(管理员)发送客户端错误警报电子邮件,以通知
    //已将错误写入ClientErrorLog文件夹。
    //#############################################################################################
    字符串errorMessage=“”;
    字符串exceptionMessage=“”;
    尝试
    {
    //实例化ControlResult以从web api获取数据。
    ControlResult ControlResult=新的ControlResult();
    // -----------------------------------------------------------------------------------------------------------------------------------------------
    //第一:此处没有可用的“用户名”-无法引用会话变量。
    //
    
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // An async override method.
        // - Fired off on exception.
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        public async override void OnException(ExceptionContext filterContext)
        {
            //#############################################################################################
            // Write a text file to the ClientErrorLog folder.
            // - It may append to the text file if it already exists.
            //#############################################################################################
    
            string strLogText = "";
            Exception ex = filterContext.Exception;
            filterContext.ExceptionHandled = true;
            var objClass = filterContext;
    
            // Set the text.
            strLogText += "Message ---\n{0}" + ex.Message;
    
            // Check the error source.
            if (ex.Source == ".Net SqlClient Data Provider")
            {
                strLogText += Environment.NewLine + "SqlClient Error ---\n{0}" + "Check Sql Error";
            }
            else if (ex.Source == "System.Web.Mvc")
            {
                strLogText += Environment.NewLine + ".Net Error ---\n{0}" + "Check MVC Code For Error";
            }
            else if (filterContext.HttpContext.Request.IsAjaxRequest() == true)
            {
                strLogText += Environment.NewLine + ".Net Error ---\n{0}" + "Check MVC Ajax Code For Error";
            }
    
            strLogText += Environment.NewLine + "Source ---\n{0}" + ex.Source;
            strLogText += Environment.NewLine + "StackTrace ---\n{0}" + ex.StackTrace;
            strLogText += Environment.NewLine + "TargetSite ---\n{0}" + ex.TargetSite;
    
            if (ex.InnerException != null)
            {
                // Error prone.
                strLogText += Environment.NewLine + "Inner Exception is {0}" + ex.InnerException;
            }
            if (ex.HelpLink != null)
            {
                // Error prone.
                strLogText += Environment.NewLine + "HelpLink ---\n{0}" + ex.HelpLink;
            }
    
            // The Textwriter for writing characters to a stream.
            StreamWriter log;
    
            // Set the date. 
            // - For instance: 27-October-2020
            string timestamp = DateTime.Now.ToString("d-MMMM-yyyy", new CultureInfo("en-GB"));
    
            // Read the web.config and get the error log path to write an 'error log' text file to.
            string error_folder = ConfigurationManager.AppSettings["ClientErrorLogPath"].ToString();
    
            // Check if the error folder exists.
            if (!System.IO.Directory.Exists(error_folder))
            {
                System.IO.Directory.CreateDirectory(error_folder);
            }
    
            // Check if the text file exists.
            // - For instance, looks for: ClientErrorLog\Log_27-October-2020.txt
            if (!File.Exists(String.Format(@"{0}\Log_{1}.txt", error_folder, timestamp)))
            {
                // Create the text file.
                log = new StreamWriter(String.Format(@"{0}\Log_{1}.txt", error_folder, timestamp));
            }
            else
            {
                // Set for an add(append) to the text file.
                log = File.AppendText(String.Format(@"{0}\Log_{1}.txt", error_folder, timestamp));
            }
    
            var controllerName = (string)filterContext.RouteData.Values["controller"];
            var actionName = (string)filterContext.RouteData.Values["action"];
    
            // Start writing to the 'error log' text file.
            // - First, write the timestamp to the file.
            log.WriteLine(Environment.NewLine + DateTime.Now);
    
            log.WriteLine("------------------------------------------------------------------------------------------------");
            log.WriteLine("Controller Name :- " + controllerName);
            log.WriteLine("Action Method Name :- " + actionName);
            log.WriteLine("------------------------------------------------------------------------------------------------");
    
            // Write the filter context.
            log.WriteLine(objClass);
    
            // Write the text.
            log.WriteLine(strLogText);
    
            // Write an empty line.
            log.WriteLine();
    
            //#############################################################################################
            // Using the web api, send a client error alert email to a staff member (an Admin) as to notify
            // that an error was written to the ClientErrorLog folder.
            //#############################################################################################
    
            string errorMessage = "";
            string exceptionMessage = "";
    
            try
            {
                // Instantiate the ControlResult for getting data from the web api.
                ControlResult controlResult = new ControlResult();
    
                // -----------------------------------------------------------------------------------------------------------------------------------------------
                // 1st: There is no 'user name' available here - can't reference the session variable.
                //        A 'user name' is needed so that the process functions properly - need to access the web api with a valid 'user name'.
                // -----------------------------------------------------------------------------------------------------------------------------------------------
    
                // Get the control control 'user name'.
                // - It calls a model class to execute a method.
                controlResult = await GetControl();
    
                // Check if an error occurred in the web api.
                if (controlResult.ApiErrorMessage == null)
                {
                    // Got the control 'user name' in order to access the web api'.
    
                    try
                    {
                        // -----------------------------------------------------------------------------------------------------------------------------------------------
                        // 2nd: Send a client error alert email to a staff member (an Admin) as to notify that an error was written to the 
                        //         ClientErrorLog folder.
                        // -----------------------------------------------------------------------------------------------------------------------------------------------
    
                        // Instantiate the ClientErrorResult for getting data from the web api.
                        ClientErrorResult clientErrorResult = new ClientErrorResult();
    
                        // Instantiate the BLL_Client class so that the functions can be referenced. 
                        BLL_ClientError bll_ClientError = new BLL_ClientError();
    
                        // Call the web api to process the error.
                        // - It calls a model class to execute a method.
                        clientErrorResult = await bll_ClientError.ProcessClientErrorNoLog(controlResult.UserName);
    
                        // Check if an error occurred in the web api.
                        if (clientErrorResult.ApiErrorMessage != null)
                        {
                            // Set the error message with the web api error message. The ReasonPhrase set in BLL_ClientError.
                            errorMessage = controlResult.ApiErrorMessage;
                        }
                    }
                    catch (Exception ex3)
                    {
                        // Friendly user message.
                        errorMessage = "Server error on sending a client error alert. Exception error: " + ex3.Message;
                    }
                }
                else
                {
                    // Set the error message with the web api error message. The ReasonPhrase set in BLL_Control.
                    errorMessage = controlResult.ApiErrorMessage;
                }
            }
            catch (Exception ex1)
            {
                // Friendly user message.
                exceptionMessage = "Server error on getting. Exception error: " + ex1.Message;
    
                try
                {
                    // Instantiate the ClientErrorResult for getting data from the web api.
                    ClientErrorResult clientErrorResult = new ClientErrorResult();
    
                    // Call the web api to process the error.
                    // Note: the 'user name' being passed. Using 'Control' as a 'user name' is not available.
                    // - It calls a model class to execute a method.
                    clientErrorResult = await ProcessClientError("Control", ex1.Message, "Server error on getting the control field. Method: OnException");
    
                    // Check if an error occurred in the web api.
                    if (clientErrorResult.ApiErrorMessage == null)
                    {
                        // All good. Just show the friendly user message set above.
                        // Pass data from the controller to the corresponding view.
                        errorMessage = exceptionMessage;
                    }
                    else
                    {
                        // Set the error message with the web api error message. The ReasonPhrase set in BLL_ClientError.
                        errorMessage = clientErrorResult.ApiErrorMessage;
                    }
                }
                catch (Exception ex2)
                {
                    // Pass data from the controller to the corresponding view.
                    errorMessage = "Failure in ProcessClientError. Exception error: " + ex2.Message + ". Original error: " + exceptionMessage;
                }
            }
    
            // Check if there was an error.
            if (errorMessage == "")
            {
                // Close the stream.
                log.Close();
    
                // Cancel the current session.
                filterContext.HttpContext.Session.Abandon();
    
                // Set the action result.
                filterContext.Result = new ViewResult()
                {
                    // Set the name of the view to render - the Views/Shared/Error.cshtml.
                    ViewName = "Error"
                };
            }
            else
            {
                // Write the error to the text file.
                // - It may append to the text file if it already exists.
    
                // Write to the 'error log' text file.
                // First, write the timestamp to the file.
                log.WriteLine(Environment.NewLine + DateTime.Now);
    
                // Set the text with a header statement.
                strLogText = "Attmpted to send a client error alert email to a staff member (an Admin) - but got an error. See it below.";
    
                // Write the text.
                log.WriteLine(strLogText);
    
                // Write an empty line.
                log.WriteLine();
    
                // Clear the previous.
                strLogText = "";
    
                // Set the text with the error message.
                strLogText += "Message ---\n{0}" + errorMessage;
    
                // Write the text.
                log.WriteLine(strLogText);
    
                // Write an empty line.
                log.WriteLine();
    
                // Close the stream.
                log.Close();
    
                // Cancel the current session.
                filterContext.HttpContext.Session.Abandon();
    
                // Set the action result.
                filterContext.Result = new ViewResult()
                {
                    // Set the name of the view to render - the Views/Shared/ErrorSendingError.cshtml.
                    ViewName = "ErrorSendingError"
                };
            }
        }
    
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // async Method.
        // Returns a model.
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        public async Task<ControlResult> GetControl()
        {
            BLL_Control bll_Control = new BLL_Control();
    
            ControlResult controlResult = new ControlResult();
    
            try
            {
                // Call the model class to get the control field.
                controlResult = await bll_Control.GetControl();
            }
            catch (Exception)
            {
                throw;
            }
    
            return controlResult;
        }
    
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // async Method.
        // Returns a model.
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        public async Task<ClientErrorResult> ProcessClientError(string userName, string errorMessage, string additionalInfo)
        {
            BLL_ClientError bll_ClientError = new BLL_ClientError();
    
            ClientErrorResult clientErrorResult = new ClientErrorResult();
    
            try
            {
                // Call the model class to process the client error.
                clientErrorResult = await bll_ClientError.ProcessClientError(userName, errorMessage, additionalInfo);
            }
            catch (Exception)
            {
                throw;
            }
    
            return clientErrorResult;
        }