如何从文件系统发送带文件的异步电子邮件?

时间:2013-08-25 20:10:39

标签: c# asp.net .net asp.net-mvc c#-4.0

我的情况是我发送一封带有图像的电子邮件作为LinkedResource。

我已经使用ImageStream来读取文件并且它可以正常工作。

问题:

当响应到达客户端时,它首先尝试访问此图像,但因为我已经发送了电子邮件异步并且它没有完成发送我收到错误,文件无法访问。

有没有更好的方法呢?

FileStream ImageStream = new FileStream(QRPath, FileMode.Open);
 System.Net.Mail.LinkedResource imageResource = new System.Net.Mail.LinkedResource(ImageStream, System.Net.Mime.MediaTypeNames.Image.Jpeg);
 imageResource.ContentId = "AttchImg";
                htmlView.LinkedResources.Add(imageResource);
SendMail(EmailMessage,true);


private void SendMail(MailMessage EmailMessage,bool IsAsync)
    {
        string FromEmail = ConfigurationSettings.AppSettings["EmailSender"];
        string FromPassword = ConfigurationSettings.AppSettings["EmailSenderPass"];
        EmailMessage.From = new System.Net.Mail.MailAddress(FromEmail);
        if (IsAsync)
        {
            try
            {
                AsyncMethodCaller caller = new AsyncMethodCaller(SendMailInSeperateThread);
                AsyncCallback callbackHandler = new AsyncCallback(AsyncCallback);
                caller.BeginInvoke(EmailMessage, callbackHandler, null);
            }
            catch (Exception ex)
            {
                //Logging
            }
        }
        else
        {
            SmtpClient smtp = new System.Net.Mail.SmtpClient();
            smtp.Host = ConfigurationSettings.AppSettings["EmailSenderSmtpHost"];
            smtp.Port = Convert.ToInt32(ConfigurationSettings.AppSettings["Port"]);//;587;
            //For google use smtp.EnableSsl = true;
            smtp.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
            smtp.Credentials = new NetworkCredential(FromEmail, FromPassword);
            smtp.Timeout = 20000;
            smtp.Send(EmailMessage);
        }
    }


    private void SendMailInSeperateThread(MailMessage message)
    {
        try
        {
            SmtpClient smtp = new System.Net.Mail.SmtpClient();
            smtp.Host = ConfigurationSettings.AppSettings["EmailSenderSmtpHost"];
            smtp.Port = Convert.ToInt32(ConfigurationSettings.AppSettings["Port"]);//;587;
            //For google use smtp.EnableSsl = true;
            smtp.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
            string FromEmail = ConfigurationSettings.AppSettings["EmailSender"];
            string FromPassword = ConfigurationSettings.AppSettings["EmailSenderPass"];

            smtp.Credentials = new NetworkCredential(FromEmail, FromPassword);
            smtp.Timeout = 20000;
            smtp.Send(message);

            //smtp.Dispose();
            //message.AlternateViews[0].LinkedResources.Dispose();
            //message.AlternateViews[1].LinkedResources.Dispose();
            //message.Dispose();

            // If you have a flag checking to see if an email was sent, set it here
            // Pass more parameters in the delegate if you need to...
        }
        catch (Exception e)
        {
            // This is very necessary to catch errors since we are in
            // a different context & thread
            //Elmah.ErrorLog.GetDefault(null).Log(new Error(e));
        }
    }

    private void AsyncCallback(IAsyncResult ar)
    {
        try
        {
            AsyncResult result = (AsyncResult)ar;
            AsyncMethodCaller caller = (AsyncMethodCaller)result.AsyncDelegate;
            caller.EndInvoke(ar);
        }
        catch (Exception e)
        {
            //Elmah.ErrorLog.GetDefault(null).Log(new Error(e));
            //Elmah.ErrorLog.GetDefault(null).Log(new Error(new Exception("Emailer - This hacky asynccallback thing is puking, serves you right.")));
        }
    }

我刚发现你可以这样做:

LinkedResource imageResource = new LinkedResource(“C:\ myImage.png”,“image / jpg”);

这是Sriram Sakthivel写的更好的方式???

1 个答案:

答案 0 :(得分:0)

尝试使用其他一个FileStream重载。

FileStream ImageStream = new FileStream(QRPath, FileMode.Open, FileAccess.Read, FileShare.Read);