使用开源opensmtp,openpop发送和接收邮件
程序员文章站
2022-07-13 16:10:52
...
因公司使用.net语言开发的开源工作流ccflow,此工作流只能发送内部邮件所以只能在其源码上新增能够发送和接收外部邮件的方法,发送邮件还是比较好整的,接收邮件第一次做还是遇到了不少问题,在网上搜了资料发现大多资料都是一样的Copy来Copy去的,以下是整理后的发送邮件和接收邮件的实例,经测试通过,附上程序压缩包,首先使用smtp发送邮件,此方法可发送附件。
/// <summary> /// 发送邮件 /// </summary> /// <param name="userEmail">邮件实体</param> /// <param name="receiver">接收者邮件地址</param> /// <param name="title">邮件主题</param> /// <param name="content">邮件内容</param> /// <param name="AttachFile">附件地址</param> /// <param name="dictionary">附件名称集合</param> protected void sendOutEMails(UserMail userEmail, String receiver, String title, String content, String AttachFile, Dictionary<int, String> dictionary) { try { // SMTP服务器 string smtpHost = "smtp." + userEmail .smtpServer+ ".com"; // SMTP服务器端口 int smtpPort = userEmail.smtpProt; // 发送者邮件地址 string senderEmail = userEmail.MailUser; // 发送者名字 string senderName = BP.Web.WebUser.Name; // 接收者邮件地址 string recipientEmail; String[] emailArr = receiver.Split('<'); if (emailArr.Length > 1) { recipientEmail = emailArr[emailArr.Length-1].Replace("<", "").Replace(">", "").Replace("《","").Replace("》",""); } else { recipientEmail = receiver; } //string recipientEmail = receiver;// "xiecanaas@126.com"; // 主题 string subject = title; // 邮件内容 string body = content; SmtpConfig.VerifyAddresses = false; EmailAddress from = new EmailAddress(senderEmail, senderName); EmailAddress to = new EmailAddress(recipientEmail); MailMessage msg = new MailMessage(from, to); // 这行一定要填上,不然收到的中文邮件是一连串的??????? msg.Charset = "UTF-8"; msg.Subject = subject; msg.Body = body; //添加附件 Attachment attachment = null; msg.Attachments.Clear(); //判断附件不为空 if (!String.IsNullOrEmpty(AttachFile)) { String[] attachPath= AttachFile.Split(';'); for (int i = 0; i < attachPath.Length-1; i++) { String pathFileName = attachPath[i]; string extName = Path.GetExtension(pathFileName).ToLower(); //获取扩展名 FileStream fs = new FileStream(Server.MapPath("/") + pathFileName, FileMode.Open, FileAccess.Read); //将附件添加到mailmessage对象 attachment = new Attachment(fs, dictionary[i]); msg.AddAttachment(attachment); } } Smtp smtp = new Smtp(smtpHost, smtpPort); // 在SMTP服务器上的用户名和密码 smtp.Username = userEmail.MailUser; smtp.Password = userEmail.MailPass; smtp.SendMail(msg); StringBuilder toList = new StringBuilder(); for (IEnumerator i = msg.To.GetEnumerator(); i.MoveNext(); ) { EmailAddress a = (EmailAddress)i.Current; toList.Append(a.Address + ";"); } } catch (MalformedAddressException mfa) { //异常处理 mfa.ToString(); } catch (SmtpException se) { //异常处理 se.ToString(); } catch (Exception ex) { //异常处理 ex.ToString(); } }
接收邮件
/// <summary> /// 外部邮箱邮件记录 /// </summary> private void ReceiveOutMails() { private readonly Pop3Client pop3Client = new Pop3Client(); object sysobj = new Object(); //while (true) //{ lock (sysobj) { try { if (pop3Client.Connected) pop3Client.Disconnect(); String code = LOGINUSER; String sqlString = String.Format("select * from OA_UserMail where UserCode='{0}' ", LOGINUSER); System.Data.DataSet dt = BP.DA.DBAccess.RunSQLReturnDataSet(sqlString); String test = dt.Tables[0].Rows[0]["popServer"].ToString(); String test2 = dt.Tables[0].Rows[0]["MailUser"].ToString(); String test3 = dt.Tables[0].Rows[0]["MailPass"].ToString(); if (dt.Tables[0].Rows.Count > 0) { //根据数据库设置获取收件服务器地址 pop3Client.Connect("pop." + dt.Tables[0].Rows[0]["popServer"].ToString() + ".com", 110, false); pop3Client.Authenticate(dt.Tables[0].Rows[0]["MailUser"].ToString(), dt.Tables[0].Rows[0]["MailPass"].ToString()); } else { return; } //通过pop对象获取信息总条数 int count = pop3Client.GetMessageCount(); int success = 0; int fail = 0; string AttachFile = null; //取得请求过来的文件结合,以下是读取邮箱邮件存储到本地 for (int i = count; i >= 1; i -= 1) { try { //得到单个Message对象 OpenPop.Mime.Message message = pop3Client.GetMessage(i); //根据MessageIdEx判断这个邮件是否已经读取 string sSql = String.Format("select * from OA_MessageEX where MessageId='{0}' ", message.Headers.MessageId); System.Data.DataSet dataSet = BP.DA.DBAccess.RunSQLReturnDataSet(sSql); //根据MessageId获取的数据集为空则证明没读取过本条记录 if (dataSet.Tables[0].Rows.Count <= 0) { //取得所有当前文件的附件集合 List<MessagePart> attachments = message.FindAllAttachments(); if (attachments.Count > 0) { //循环附件 foreach (MessagePart attachment in attachments) { //生成地址 string dir = this.GetAttachPathName(); if (!System.IO.Directory.Exists(Server.MapPath(dir))) System.IO.Directory.CreateDirectory(Server.MapPath(dir)); //文件名称 string newFileName = this.GetAttachFileName(attachment.FileName); //文件路径 string path = String.Format("{0}/{1}", dir, newFileName); //string filePath = this.FileUpload1.PostedFile.FileName; WebClient myWebClient = new WebClient(); myWebClient.Credentials = CredentialCache.DefaultCredentials; try { //打开远程Web地址,将文件流写入 Stream postStream = myWebClient.OpenWrite(Server.MapPath("/") + path, "PUT"); if (postStream.CanWrite) { postStream.Write(attachment.Body, 0, attachment.Body.Length); } else { //MessageBox.Show("Web服务器文件目前不可写入,请检查Web服务器目录权限设置!","系统提示",MessageBoxButtons.OK,MessageBoxIcon.Information); } postStream.Close();//关闭流 AttachFile += String.Format("{0};", path); } catch { ; } } //清除邮件集合 attachments.Clear(); } //新增邮件信息表 MessagePart plainTextPart = message.FindFirstPlainTextVersion(); BP.OA.Message.Message msg = new BP.OA.Message.Message(); DateTime AddTime = DateTime.Now; //判断内容区域是否为文字类型 String Doc=""; try { Doc = plainTextPart.GetBodyAsText(); } catch (Exception) { Doc = "<<OpenPop>> Cannot show this part of the email. It is not text <<OpenPop>>"; } String FK_UserNo = LOGINUSER; int MessageState = 1; String SendToUsers = ""; String CopyToUsers = ""; System.Data.DataSet messageData = this.getMaxOID(); String OID = messageData.Tables[0].Rows[0]["OID"].ToString(); if (message.Headers.To.Count > 0) foreach (RfcMailAddress to in message.Headers.To) SendToUsers += String.Format("{0},", to).TrimEnd(','); if (message.Headers.Cc.Count > 0) foreach (RfcMailAddress cc in message.Headers.Cc) CopyToUsers += String.Format("{0},", cc).TrimEnd(','); String AttachFiles = AttachFile; String Title = message.Headers.Subject; String MessageIdEx = message.Headers.MessageId; //插入数据到OA_Message String messageInsertSql = String.Format("Insert into OA_Message (AddTime,Title,AttachFile,Doc,FK_UserNo,MessageState,SendToUsers,CopyToUsers,MessageIdEx,OID) values('{0}','{1}','{2}','{3}','{4}',{5},'{6}','{7}','{8}',{9})", AddTime, Title, AttachFiles, Doc, FK_UserNo, MessageState, SendToUsers, CopyToUsers, MessageIdEx, Convert.ToInt32(OID) + 1); doNonQuery(messageInsertSql); //插入数据到OA_MessageEX String messageExSql = String.Format("Insert into OA_MessageEX (MessageId) values('{0}')", message.Headers.MessageId); doNonQuery(messageExSql); //msg.Insert(); //附件地址插入成功后将地址清空 AttachFile = null; //if (msg.OID == 0) //{ // this.Alert("邮件读取失败!"); return; //} #region 插入数据到收件箱表 if (true) { //获取OA_MessageInBox表最大OID System.Data.DataSet messageInBoxData = this.getOA_MessageInBoxMaxOID(); String maxOA_MessageInBoxOID = messageInBoxData.Tables[0].Rows[0]["OID"].ToString(); foreach (RfcMailAddress to in message.Headers.To) { if (String.Format("{0},", to).IndexOf("@") > 0) { //收件箱 n个人 //获取OA_Message表最大OID System.Data.DataSet dataSets = this.getMaxOID(); AddTime = DateTime.Now; String FK_MsgNo = dataSets.Tables[0].Rows[0]["OID"].ToString(); String FK_ReceiveUserNo = to.ToString(); String Sender = message.Headers.From.ToString(); //Boolean Received = false; //Boolean IsCopy = false; //是否抄送标志 String inBoxSql = String.Format("Insert into OA_MessageInBox(FK_MsgNo,FK_ReceiveUserNo,Sender,AddTime,Received,IsCopy,OID) values({0},'{1}','{2}','{3}',{4},{5},{6})", FK_MsgNo, FK_ReceiveUserNo, Sender, AddTime, 0, 0, Convert.ToInt32(maxOA_MessageInBoxOID) + 1); doNonQuery(inBoxSql); //ib.Insert(); } else { //收件箱 n个人 System.Data.DataSet dataSets = this.getMaxOID(); AddTime = DateTime.Now; int FK_MsgNo = Convert.ToInt32(dataSets.Tables[0].Rows[0]["OID"].ToString());; String FK_ReceiveUserNo = String.Format("{0},", to); String Sender = message.Headers.From.ToString(); Boolean Received = false; Boolean IsCopy = false; //是否抄送标志 //ib.Insert(); String inBoxSql = String.Format("Insert into OA_MessageInBox(FK_MsgNo,FK_ReceiveUserNo,Sender,AddTime,Received,IsCopy) values({0},'{1}','{2}','{3}',{4},{5},{6})", FK_MsgNo, FK_ReceiveUserNo, Sender, AddTime, 0, 0, Convert.ToInt32(maxOA_MessageInBoxOID) + 1); doNonQuery(inBoxSql); int newId = dataSets.Tables[0].Rows[0]["OID"].ToString() !="" ? Convert.ToInt32( dataSets.Tables[0].Rows[0]["OID"]):0; if (newId == 0) continue; } } } #endregion #region 插入数据到收件箱主题表 if (true) { //获取OA_MessageInBox表最大OID System.Data.DataSet messageInBoxData = this.getOA_MessageInBoxMaxOID(); String maxOA_MessageInBoxOID = messageInBoxData.Tables[0].Rows[0]["OID"].ToString(); //发送给抄送人 foreach (RfcMailAddress cc in message.Headers.Cc) { if (String.Format("{0},", cc).IndexOf("@") > 0) { //收件箱 n个人 System.Data.DataSet dataSets = this.getMaxOID(); AddTime = DateTime.Now; int FK_MsgNo = Convert.ToInt32( dataSets.Tables[0].Rows[0]["OID"].ToString()); ; String FK_ReceiveUserNo = String.Format("{0},", cc); String Sender = message.Headers.From.ToString(); Boolean Received = false; Boolean IsCopy = true; //是否抄送标志 String inBoxSql = String.Format("Insert into OA_MessageInBox(FK_MsgNo,FK_ReceiveUserNo,Sender,AddTime,Received,IsCopy) values({0},'{1}','{2}','{3}',{4},{5},{6})", FK_MsgNo, FK_ReceiveUserNo, Sender, AddTime, 0, 1, Convert.ToInt32(maxOA_MessageInBoxOID) + 1); doNonQuery(inBoxSql); // ib.Insert(); } else { //收件箱 n个人 System.Data.DataSet dataSets = this.getMaxOID(); AddTime = DateTime.Now; int FK_MsgNo = Convert.ToInt32(dataSets.Tables[0].Rows[0]["OID"].ToString()); String FK_ReceiveUserNo = String.Format("{0},", String.Format("{0},", cc)); String Sender = message.Headers.From.ToString(); Boolean Received = false; Boolean IsCopy = true; //是否抄送标志 // ib.Insert(); String inBoxSql = String.Format("Insert into OA_MessageInBox(FK_MsgNo,FK_ReceiveUserNo,Sender,AddTime,Received,IsCopy) values({0},'{1}','{2}','{3}',{4},{5},{6})", FK_MsgNo, FK_ReceiveUserNo, Sender, AddTime, 0, 1, Convert.ToInt32(maxOA_MessageInBoxOID) + 1); doNonQuery(inBoxSql); int newId = dataSets.Tables[0].Rows[0]["OID"].ToString() != "" ? Convert.ToInt32(dataSets.Tables[0].Rows[0]["OID"]) : 0; if (newId == 0) continue; } } } #endregion success++; } } catch (Exception e) { DefaultLogger.Log.LogError( "TestForm: Message fetching failed: " + e.Message + "\r\n" + "Stack trace:\r\n" + e.StackTrace); fail++; } ; } if (fail > 0) { this.Alert("邮件读取失败!"); return; } } catch (InvalidLoginException) { ; } catch (PopServerNotFoundException) { ; } catch (PopServerLockedException) { ; } catch (LoginDelayException) { ; } catch (Exception e) { ; } ; } }
openpop 接收邮件
// 声明成员变量 private readonly Pop3Client pop3Client = new Pop3Client(); /// <summary> /// 外部邮箱邮件记录 /// </summary> private void ReceiveOutMails() { private readonly Pop3Client pop3Client = new Pop3Client(); object sysobj = new Object(); //while (true) //{ lock (sysobj) { try { if (pop3Client.Connected) pop3Client.Disconnect(); String code = LOGINUSER; String sqlString = String.Format("select * from OA_UserMail where UserCode='{0}' ", LOGINUSER); System.Data.DataSet dt = BP.DA.DBAccess.RunSQLReturnDataSet(sqlString); String test = dt.Tables[0].Rows[0]["popServer"].ToString(); String test2 = dt.Tables[0].Rows[0]["MailUser"].ToString(); String test3 = dt.Tables[0].Rows[0]["MailPass"].ToString(); if (dt.Tables[0].Rows.Count > 0) { //根据数据库设置获取收件服务器地址 pop3Client.Connect("pop." + dt.Tables[0].Rows[0]["popServer"].ToString() + ".com", 110, false); pop3Client.Authenticate(dt.Tables[0].Rows[0]["MailUser"].ToString(), dt.Tables[0].Rows[0]["MailPass"].ToString()); } else { return; } //通过pop对象获取信息总条数 int count = pop3Client.GetMessageCount(); int success = 0; int fail = 0; string AttachFile = null; //取得请求过来的文件结合,以下是读取邮箱邮件存储到本地 for (int i = count; i >= 1; i -= 1) { try { //得到单个Message对象 OpenPop.Mime.Message message = pop3Client.GetMessage(i); //根据MessageIdEx判断这个邮件是否已经读取 string sSql = String.Format("select * from OA_MessageEX where MessageId='{0}' ", message.Headers.MessageId); System.Data.DataSet dataSet = BP.DA.DBAccess.RunSQLReturnDataSet(sSql); //根据MessageId获取的数据集为空则证明没读取过本条记录 if (dataSet.Tables[0].Rows.Count <= 0) { //取得所有当前文件的附件集合 List<MessagePart> attachments = message.FindAllAttachments(); if (attachments.Count > 0) { //循环附件 foreach (MessagePart attachment in attachments) { //生成地址 string dir = this.GetAttachPathName(); if (!System.IO.Directory.Exists(Server.MapPath(dir))) System.IO.Directory.CreateDirectory(Server.MapPath(dir)); //文件名称 string newFileName = this.GetAttachFileName(attachment.FileName); //文件路径 string path = String.Format("{0}/{1}", dir, newFileName); //string filePath = this.FileUpload1.PostedFile.FileName; WebClient myWebClient = new WebClient(); myWebClient.Credentials = CredentialCache.DefaultCredentials; try { //打开远程Web地址,将文件流写入 Stream postStream = myWebClient.OpenWrite(Server.MapPath("/") + path, "PUT"); if (postStream.CanWrite) { postStream.Write(attachment.Body, 0, attachment.Body.Length); } else { //MessageBox.Show("Web服务器文件目前不可写入,请检查Web服务器目录权限设置!","系统提示",MessageBoxButtons.OK,MessageBoxIcon.Information); } postStream.Close();//关闭流 AttachFile += String.Format("{0};", path); } catch { ; } } //清除邮件集合 attachments.Clear(); } //新增邮件信息表 MessagePart plainTextPart = message.FindFirstPlainTextVersion(); BP.OA.Message.Message msg = new BP.OA.Message.Message(); DateTime AddTime = DateTime.Now; //判断内容区域是否为文字类型 String Doc=""; try { Doc = plainTextPart.GetBodyAsText(); } catch (Exception) { Doc = "<<OpenPop>> Cannot show this part of the email. It is not text <<OpenPop>>"; } String FK_UserNo = LOGINUSER; int MessageState = 1; String SendToUsers = ""; String CopyToUsers = ""; System.Data.DataSet messageData = this.getMaxOID(); String OID = messageData.Tables[0].Rows[0]["OID"].ToString(); if (message.Headers.To.Count > 0) foreach (RfcMailAddress to in message.Headers.To) SendToUsers += String.Format("{0},", to).TrimEnd(','); if (message.Headers.Cc.Count > 0) foreach (RfcMailAddress cc in message.Headers.Cc) CopyToUsers += String.Format("{0},", cc).TrimEnd(','); String AttachFiles = AttachFile; String Title = message.Headers.Subject; String MessageIdEx = message.Headers.MessageId; //插入数据到OA_Message String messageInsertSql = String.Format("Insert into OA_Message (AddTime,Title,AttachFile,Doc,FK_UserNo,MessageState,SendToUsers,CopyToUsers,MessageIdEx,OID) values('{0}','{1}','{2}','{3}','{4}',{5},'{6}','{7}','{8}',{9})", AddTime, Title, AttachFiles, Doc, FK_UserNo, MessageState, SendToUsers, CopyToUsers, MessageIdEx, Convert.ToInt32(OID) + 1); doNonQuery(messageInsertSql); //插入数据到OA_MessageEX String messageExSql = String.Format("Insert into OA_MessageEX (MessageId) values('{0}')", message.Headers.MessageId); doNonQuery(messageExSql); //msg.Insert(); //附件地址插入成功后将地址清空 AttachFile = null; //if (msg.OID == 0) //{ // this.Alert("邮件读取失败!"); return; //} #region 插入数据到收件箱表 if (true) { //获取OA_MessageInBox表最大OID System.Data.DataSet messageInBoxData = this.getOA_MessageInBoxMaxOID(); String maxOA_MessageInBoxOID = messageInBoxData.Tables[0].Rows[0]["OID"].ToString(); foreach (RfcMailAddress to in message.Headers.To) { if (String.Format("{0},", to).IndexOf("@") > 0) { //收件箱 n个人 //获取OA_Message表最大OID System.Data.DataSet dataSets = this.getMaxOID(); AddTime = DateTime.Now; String FK_MsgNo = dataSets.Tables[0].Rows[0]["OID"].ToString(); String FK_ReceiveUserNo = to.ToString(); String Sender = message.Headers.From.ToString(); //Boolean Received = false; //Boolean IsCopy = false; //是否抄送标志 String inBoxSql = String.Format("Insert into OA_MessageInBox(FK_MsgNo,FK_ReceiveUserNo,Sender,AddTime,Received,IsCopy,OID) values({0},'{1}','{2}','{3}',{4},{5},{6})", FK_MsgNo, FK_ReceiveUserNo, Sender, AddTime, 0, 0, Convert.ToInt32(maxOA_MessageInBoxOID) + 1); doNonQuery(inBoxSql); //ib.Insert(); } else { //收件箱 n个人 System.Data.DataSet dataSets = this.getMaxOID(); AddTime = DateTime.Now; int FK_MsgNo = Convert.ToInt32(dataSets.Tables[0].Rows[0]["OID"].ToString());; String FK_ReceiveUserNo = String.Format("{0},", to); String Sender = message.Headers.From.ToString(); Boolean Received = false; Boolean IsCopy = false; //是否抄送标志 //ib.Insert(); String inBoxSql = String.Format("Insert into OA_MessageInBox(FK_MsgNo,FK_ReceiveUserNo,Sender,AddTime,Received,IsCopy) values({0},'{1}','{2}','{3}',{4},{5},{6})", FK_MsgNo, FK_ReceiveUserNo, Sender, AddTime, 0, 0, Convert.ToInt32(maxOA_MessageInBoxOID) + 1); doNonQuery(inBoxSql); int newId = dataSets.Tables[0].Rows[0]["OID"].ToString() !="" ? Convert.ToInt32( dataSets.Tables[0].Rows[0]["OID"]):0; if (newId == 0) continue; } } } #endregion #region 插入数据到收件箱主题表 if (true) { //获取OA_MessageInBox表最大OID System.Data.DataSet messageInBoxData = this.getOA_MessageInBoxMaxOID(); String maxOA_MessageInBoxOID = messageInBoxData.Tables[0].Rows[0]["OID"].ToString(); //发送给抄送人 foreach (RfcMailAddress cc in message.Headers.Cc) { if (String.Format("{0},", cc).IndexOf("@") > 0) { //收件箱 n个人 System.Data.DataSet dataSets = this.getMaxOID(); AddTime = DateTime.Now; int FK_MsgNo = Convert.ToInt32( dataSets.Tables[0].Rows[0]["OID"].ToString()); ; String FK_ReceiveUserNo = String.Format("{0},", cc); String Sender = message.Headers.From.ToString(); Boolean Received = false; Boolean IsCopy = true; //是否抄送标志 String inBoxSql = String.Format("Insert into OA_MessageInBox(FK_MsgNo,FK_ReceiveUserNo,Sender,AddTime,Received,IsCopy) values({0},'{1}','{2}','{3}',{4},{5},{6})", FK_MsgNo, FK_ReceiveUserNo, Sender, AddTime, 0, 1, Convert.ToInt32(maxOA_MessageInBoxOID) + 1); doNonQuery(inBoxSql); // ib.Insert(); } else { //收件箱 n个人 System.Data.DataSet dataSets = this.getMaxOID(); AddTime = DateTime.Now; int FK_MsgNo = Convert.ToInt32(dataSets.Tables[0].Rows[0]["OID"].ToString()); String FK_ReceiveUserNo = String.Format("{0},", String.Format("{0},", cc)); String Sender = message.Headers.From.ToString(); Boolean Received = false; Boolean IsCopy = true; //是否抄送标志 // ib.Insert(); String inBoxSql = String.Format("Insert into OA_MessageInBox(FK_MsgNo,FK_ReceiveUserNo,Sender,AddTime,Received,IsCopy) values({0},'{1}','{2}','{3}',{4},{5},{6})", FK_MsgNo, FK_ReceiveUserNo, Sender, AddTime, 0, 1, Convert.ToInt32(maxOA_MessageInBoxOID) + 1); doNonQuery(inBoxSql); int newId = dataSets.Tables[0].Rows[0]["OID"].ToString() != "" ? Convert.ToInt32(dataSets.Tables[0].Rows[0]["OID"]) : 0; if (newId == 0) continue; } } } #endregion success++; } } catch (Exception e) { DefaultLogger.Log.LogError( "TestForm: Message fetching failed: " + e.Message + "\r\n" + "Stack trace:\r\n" + e.StackTrace); fail++; } ; } if (fail > 0) { this.Alert("邮件读取失败!"); return; } } catch (InvalidLoginException) { ; } catch (PopServerNotFoundException) { ; } catch (PopServerLockedException) { ; } catch (LoginDelayException) { ; } catch (Exception e) { ; } ; } }