【问题标题】:Sending email with attachments from C#, attachments arrive as Part 1.2 in Thunderbird从 C# 发送带有附件的电子邮件,附件在 Thunderbird 中作为第 1.2 部分到达
【发布时间】:2011-02-19 00:52:33
【问题描述】:

我有一个 C# 应用程序,它使用 SMTP 通过 Exchange 2007 服务器通过电子邮件发送 Excel 电子表格报告。这些附件对 Outlook 用户来说很好,但对于 Thunderbird 和 Blackberry 用户来说,附件已重命名为“第 1.2 部分”。

我发现这个article 描述了这个问题,但似乎没有给我一个解决方法。我无法控制 Exchange 服务器,因此无法在那里进行更改。在 C# 端有什么我可以做的吗?我曾尝试对正文使用短文件名和 HTML 编码,但都没有任何区别。

我的邮件发送代码是这样的:

public static void SendMail(string recipient, string subject, string body, string attachmentFilename)
{
    SmtpClient smtpClient = new SmtpClient();
    NetworkCredential basicCredential = new NetworkCredential(MailConst.Username, MailConst.Password);
    MailMessage message = new MailMessage();
    MailAddress fromAddress = new MailAddress(MailConst.Username);

    // setup up the host, increase the timeout to 5 minutes
    smtpClient.Host = MailConst.SmtpServer;
    smtpClient.UseDefaultCredentials = false;
    smtpClient.Credentials = basicCredential;
    smtpClient.Timeout = (60 * 5 * 1000);

    message.From = fromAddress;
    message.Subject = subject;
    message.IsBodyHtml = false;
    message.Body = body;
    message.To.Add(recipient);

    if (attachmentFilename != null)
        message.Attachments.Add(new Attachment(attachmentFilename));

    smtpClient.Send(message);
}

感谢您的帮助。

【问题讨论】:

  • 您是否尝试定义/更改Attachment.Name 属性?
  • 不,我没有 - “获取或设置 MIME 内容类型名称值”,您对尝试什么值有什么建议吗?谢谢。
  • 当收到带有附件的电子邮件时,Name 显示为附件的名称。所以你可以尝试任何值。

标签: c# email smtp attachment


【解决方案1】:

在您的电子邮件服务下使用此方法,它可以将任何电子邮件正文和附件附加到 Microsoft Outlook

使用 Outlook = Microsoft.Office.Interop.Outlook; // 如果您稍后将使用构建代理,请从本地或 nuget 引用 Microsoft.Office.Interop.Outlook

 try {
                    var officeType = Type.GetTypeFromProgID("Outlook.Application");
    
                    if(officeType == null) {//outlook is not installed
                        return new PdfErrorResponse {
                            ErrorMessage = "System cant start Outlook!, make sure outlook is installed on your computer."
                        };
                    } else {
                        // Outlook is installed.    
                        // Continue your work.
                        Outlook.Application objApp = new Outlook.Application();
                        Outlook.MailItem mail = null;
                        mail = (Outlook.MailItem)objApp.CreateItem(Outlook.OlItemType.olMailItem);
                        //The CreateItem method returns an object which has to be typecast to MailItem 
                        //before using it.
                        mail.Attachments.Add(attachmentFilePath,Outlook.OlAttachmentType.olEmbeddeditem,1,$"Attachment{ordernumber}");
                        //The parameters are explained below
                        mail.To = recipientEmailAddress;
                        //mail.CC = "con@def.com";//All the mail lists have to be separated by the ';'
    
                        //To send email:
                        //mail.Send();
                        //To show email window
                        await Task.Run(() => mail.Display());
                    }
    
                } catch(System.Exception) {
                    return new PdfErrorResponse {
                        ErrorMessage = "System cant start Outlook!, make sure outlook is installed on your computer."
                    };
                }

【讨论】:

    【解决方案2】:

    显式填写 ContentDisposition 字段就可以了。

    if (attachmentFilename != null)
    {
        Attachment attachment = new Attachment(attachmentFilename, MediaTypeNames.Application.Octet);
        ContentDisposition disposition = attachment.ContentDisposition;
        disposition.CreationDate = File.GetCreationTime(attachmentFilename);
        disposition.ModificationDate = File.GetLastWriteTime(attachmentFilename);
        disposition.ReadDate = File.GetLastAccessTime(attachmentFilename);
        disposition.FileName = Path.GetFileName(attachmentFilename);
        disposition.Size = new FileInfo(attachmentFilename).Length;
        disposition.DispositionType = DispositionTypeNames.Attachment;
        message.Attachments.Add(attachment);                
    }
    

    顺便说一句,对于 Gmail,您可能会遇到一些关于 ssl 安全甚至端口的例外情况!

    smtpClient.EnableSsl = true;
    smtpClient.Port = 587;
    

    【讨论】:

    • 为什么不使用FileInfo 对象来获取CreationTimeLastWriteTimeLastAccessTime 属性?无论如何,您正在创建一个以获取 Length 属性。
    • 不要忘记 attachment.Dispose() 否则此文件将保持锁定状态,您将无法在其上写入数据。
    【解决方案3】:

    我为此编写了一个简短的代码,我想与您分享。

    这里是主要代码:

    public void Send(string from, string password, string to, string Message, string subject, string host, int port, string file)
    {
    
      MailMessage email = new MailMessage();
      email.From = new MailAddress(from);
      email.To.Add(to);
      email.Subject = subject;
      email.Body = Message;
      SmtpClient smtp = new SmtpClient(host, port);
      smtp.UseDefaultCredentials = false;
      NetworkCredential nc = new NetworkCredential(from, password);
      smtp.Credentials = nc;
      smtp.EnableSsl = true;
      email.IsBodyHtml = true;
      email.Priority = MailPriority.Normal;
      email.BodyEncoding = Encoding.UTF8;
    
      if (file.Length > 0)
      {
        Attachment attachment;
        attachment = new Attachment(file);
        email.Attachments.Add(attachment);
      }
    
      // smtp.Send(email);
      smtp.SendCompleted += new SendCompletedEventHandler(SendCompletedCallBack);
      string userstate = "sending ...";
      smtp.SendAsync(email, userstate);
    }
    
    private static void SendCompletedCallBack(object sender,AsyncCompletedEventArgs e) {
      string result = "";
      if (e.Cancelled)
      {    
        MessageBox.Show(string.Format("{0} send canceled.", e.UserState),"Message",MessageBoxButtons.OK,MessageBoxIcon.Information);
      }
      else if (e.Error != null)
      {
        MessageBox.Show(string.Format("{0} {1}", e.UserState, e.Error), "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
      }
      else {
        MessageBox.Show("your message is sended", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
      }
    
    }
    

    在你的按钮中做这样的事情
    你可以添加你的 jpg 或 pdf 文件等等。这只是一个例子

    using (OpenFileDialog attachement = new OpenFileDialog()
    {
      Filter = "Exel Client|*.png",
      ValidateNames = true
    })
    {
    if (attachement.ShowDialog() == DialogResult.OK)
    {
      Send("yourmail@gmail.com", "gmail_password", 
           "tomail@gmail.com", "just smile ", "mail with attachement",
           "smtp.gmail.com", 587, attachement.FileName);
    
    }
    }
    

    【讨论】:

      【解决方案4】:

      我尝试了 Ranadheer Reddy(上图)提供的代码,效果很好。如果您使用的公司计算机具有受限服务器,您可能需要将 SMTP 端口更改为 25 并将您的用户名和密码留空,因为它们将由您的管理员自动填写。

      最初,我尝试使用来自 nugent 包管理器的 EASendMail,却发现它是付费版本,有 30 天试用期。除非您打算购买它,否则不要浪费时间。我注意到程序使用 EASendMail 运行得更快,但对我来说,免费胜过快速。

      只值我的 2 美分。

      【讨论】:

        【解决方案5】:

        发送带有附件的电子邮件的简单代码。

        来源:http://www.coding-issues.com/2012/11/sending-email-with-attachments-from-c.html

        using System.Net;
        using System.Net.Mail;
        
        public void email_send()
        {
            MailMessage mail = new MailMessage();
            SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
            mail.From = new MailAddress("your mail@gmail.com");
            mail.To.Add("to_mail@gmail.com");
            mail.Subject = "Test Mail - 1";
            mail.Body = "mail with attachment";
        
            System.Net.Mail.Attachment attachment;
            attachment = new System.Net.Mail.Attachment("c:/textfile.txt");
            mail.Attachments.Add(attachment);
        
            SmtpServer.Port = 587;
            SmtpServer.Credentials = new System.Net.NetworkCredential("your mail@gmail.com", "your password");
            SmtpServer.EnableSsl = true;
        
            SmtpServer.Send(mail);
        
        }
        

        【讨论】:

        • 你应该用 using 语句包装 MailMessage 和 SmtpClient 以确保它们被正确处理
        • @Andrew - 我该怎么做?
        • 我试过这段代码,我得到了这篇文章中显示的错误 - stackoverflow.com/questions/20845469/…
        • @Steam 你可以这样做using(SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com")) { //code goes here using(MailMessage mail = new MailMessage()){ //code goes here } }
        【解决方案6】:
        private void btnSent_Click(object sender, EventArgs e)
        {
            try
            {
                MailMessage mail = new MailMessage();
                SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
        
                mail.From = new MailAddress(txtAcc.Text);
                mail.To.Add(txtToAdd.Text);
                mail.Subject = txtSub.Text;
                mail.Body = txtContent.Text;
                System.Net.Mail.Attachment attachment;
                attachment = new System.Net.Mail.Attachment(txtAttachment.Text);
                mail.Attachments.Add(attachment);
        
                SmtpServer.Port = 587;
                SmtpServer.Credentials = new System.Net.NetworkCredential(txtAcc.Text, txtPassword.Text);
        
                SmtpServer.EnableSsl = true;
        
                SmtpServer.Send(mail);
                MessageBox.Show("mail send");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            MailMessage mail = new MailMessage();
            openFileDialog1.ShowDialog();
            System.Net.Mail.Attachment attachment;
            attachment = new System.Net.Mail.Attachment(openFileDialog1.FileName);
            mail.Attachments.Add(attachment);
            txtAttachment.Text =Convert.ToString (openFileDialog1.FileName);
        }
        

        【讨论】:

          【解决方案7】:

          这是一个带有附件的简单邮件发送代码

          try  
          {  
              SmtpClient mailServer = new SmtpClient("smtp.gmail.com", 587);  
              mailServer.EnableSsl = true;  
          
              mailServer.Credentials = new System.Net.NetworkCredential("myemail@gmail.com", "mypassword");  
          
              string from = "myemail@gmail.com";  
              string to = "reciever@gmail.com";  
              MailMessage msg = new MailMessage(from, to);  
              msg.Subject = "Enter the subject here";  
              msg.Body = "The message goes here.";
              msg.Attachments.Add(new Attachment("D:\\myfile.txt"));
              mailServer.Send(msg);  
          }  
          catch (Exception ex)  
          {  
              Console.WriteLine("Unable to send email. Error : " + ex);  
          }
          

          阅读更多Sending emails with attachment in C#

          【讨论】:

            【解决方案8】:

            试试这个:

            private void btnAtt_Click(object sender, EventArgs e) {
            
                openFileDialog1.ShowDialog();
                Attachment myFile = new Attachment(openFileDialog1.FileName);
            
                MyMsg.Attachments.Add(myFile);
            
            
            }
            

            【讨论】:

              【解决方案9】:

              完成Ranadheer的解决方案,使用Server.MapPath定位文件

              System.Net.Mail.Attachment attachment;
              attachment = New System.Net.Mail.Attachment(Server.MapPath("~/App_Data/hello.pdf"));
              mail.Attachments.Add(attachment);
              

              【讨论】:

              • Server.MapPath 来自哪里,应该在什么时候使用?
              • 写这本书的人可能是 ASP.NET 程序员,我认为从相对文件名中给出完整的限定文件名会有所帮助。最初的问题没有提到 ASP.NET;您可以在此处放置对文件名的完整引用。
              猜你喜欢
              • 2015-11-25
              • 2011-11-10
              • 2015-09-09
              • 2015-04-24
              • 2015-08-28
              相关资源
              最近更新 更多