【问题标题】:Programmatically disposing of the Elmah email onMailing以编程方式处理 Elmah 电子邮件 onMailing
【发布时间】:2012-08-22 00:04:42
【问题描述】:

我对 Elmah 有疑问,我已经覆盖了 Mailing 方法。我希望它在我的应用程序不处于实时模式时处理邮件(基本上不发送)。问题是当我这样做时,当我的 ErrorHandler(在我的 ASP.NET MVC 应用程序中)尝试使用 Elmah 引发异常时,我收到错误:无法访问已处置的对象。对象名称:'System.Net.Mail.MailMessage'。所以我需要想办法解决这个问题。代码如下:

电邮方式:

public static void ErrorMail_Mailing(object sender, ErrorMailEventArgs e)
        {
            if (!GlobalHelper.IsLiveMode)
            {

                //e.Mail.Dispose();
            }
            else
            {
                MailAddressCollection MAC = new MailAddressCollection();
                foreach (string a in EmailRecipients.Split(','))
                {
                    MAC.Add(a);
                }

                string b = "errors@" + GlobalHelper.AppName + ".com";
                e.Mail.From = new MailAddress(b);
                e.Mail.To.Clear(); // Clears existing mail addresses
                e.Mail.To.Add(MAC.ToString());
                e.Mail.Subject = GlobalHelper.AppName+ " Error: ("+e.Error.Type.Substring(0,10)+") Deployment Level:"+GlobalHelper.DeploymentMode;

            }

错误处理方法:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    public class CustomHandleErrorAttribute : HandleErrorAttribute
    {

        public override void OnException(ExceptionContext context)
        {
            // Bail if we can't do anything; app will crash.
            if (context == null)
                return;
            var ex = context.Exception ?? new Exception("No further information exists.");

            // Can show Data on view page /w this code
            // var data = new ErrorPresentation
            //{
            //  ErrorMessage = HttpUtility.HtmlEncode(ex.Message),
            //  TheException = ex,
            //  ShowMessage = !(filterContext.Exception == null),
            //  ShowLink = false
            //};
            //filterContext.Result = View("ErrorPage", data);

            context.ExceptionHandled = true;

            //Log to Elmah
            ErrorSignal.FromCurrentContext().Raise(ex);

            //Show Custom view page
            context.Result = new ViewResult { ViewName = "Error" };
        }
    }

堆栈跟踪:

System.Net.Mail.SmtpException: Failure sending mail. ---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Mail.MailMessage'.
   at System.Net.Mail.MailMessage.get_AlternateViews()
   at System.Net.Mail.MailMessage.SetContent()
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   --- End of inner exception stack trace ---
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at Elmah.ErrorMailModule.SendMail(MailMessage mail)
   at Elmah.ErrorMailModule.ReportError(Error error)
   at Elmah.ErrorMailModule.OnError(Exception e, HttpContext context)
   at Elmah.ErrorMailModule.OnErrorSignaled(Object sender, ErrorSignalEventArgs args)
   at Elmah.ErrorSignalEventHandler.Invoke(Object sender, ErrorSignalEventArgs args)
   at Elmah.ErrorSignal.Raise(Exception e, HttpContext context)
   at Elmah.ErrorSignal.Raise(Exception e)
   at MusingMonkey.Utilities.Filters.CustomHandleErrorAttribute.OnException(ExceptionContext context) in C:\Users\William-Business\Desktop\TWB\TWB Central\Projects\MusingMonkey\MusingMonkey\Utilities\Filters\ErrorHandler.cs:line 34
   at System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList`1 filters, Exception exception)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state)
   at System.Web.Mvc.Controller.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__3(AsyncCallback asyncCallback, Object asyncState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<BeginProcessRequest>b__2()
   at System.Web.Mvc.SecurityUtil.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a()
   at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
   at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
   at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust[TResult](Func`1 func)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

【问题讨论】:

    标签: asp.net asp.net-mvc elmah


    【解决方案1】:

    问题是 ELMAH 正在尝试使用 MailMessage 来发送它,但您已经处置了该对象。对您来说最好的解决方案是不要通过事件执行此操作,而是通过继承 ErrorMailModule 并覆盖它的 SendMail 方法,如下所示:

    protected override void SendMail(MailMessage mail)
    {
        if (!GlobalHelper.IsLiveMode) 
            base.SendMail(mail);
    }
    

    然后您可以继续在您的 Mailing 事件处理程序中完成其余的工作。

    【讨论】:

    • 嘿 Atif,我试过这样做,但我无法让 web.config 找到我的自定义 elmah 类!
    • 这可能是我们可以在ELMAH discussion group 上单独讨论的问题吗?我想在这里解决短 cmets 中的配置问题可能会很困难。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 2013-10-07
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多