关于.NET邮件的收发问题总结

        最近因为项目需要,研究了一下邮件的发送和接收,发现现在这方面的问题很多.虽然网上这方面的资料很多,但是真正应用起来 仍然会发现不少问题,而且很多人都抱怨书上或者网上的一些代码应用起来是失败的,并且针对附件方面的处理不太完善,针对这种情况我把最近研究所得做一个小小的总结,希望能对大家有所帮助。         首先来谈谈发送邮件的问题。

       发送邮件现在应用得最多的两种情况就是利用.NET自带的发送邮件和利用jmail组件来发送邮件。        .NET自带的邮件发送利用了System.Web.Mail.MailMessage这个类,这是在VS2003的情况下,在VS2005下更多的是利用System.Net.Mail.MailMessage,下面的例子是在VS2003的情况下写的,请在应用的时候自己替换掉里面的参数。

string SendTos=SendTo.Text.Trim();  //发送人
            string CcTos=CcTo.Text.Trim();      //抄送人
            string[] Receiver=System.Text.RegularExpressions.Regex.Split(SendTos+CcTos,",");  //总收件人
            string FromMail="ustbwuyi1@163.com";//发件人
            string Title="你好"; //邮件主题
            string Body="附件里重要文档,请查收!";   //邮件主体
            string ShowName="ustbwuyi";//显示名字

            if(SendTos!="" || CcTos!="")
            {
                //用户名(取发送邮箱的@前面的部分,即ustbwuyi1
                string MailUserName=FromMail.Substring(,FromMail.IndexOf("@"));

                //密码
                string MailPassword="ustbwuyi";
                System.Web.Mail.MailMessage mailmessage=new MailMessage();
                mailmessage.From=FromMail;
                mailmessage.Subject=Title;
                mailmessage.Body=Body;

                //添加附件

                ArrayList FileNames;
                //如果存在附件
                if(FileNames.Count>=)
                {                    
                    //添加附件
                        string Filename;
                        for(int k=;k<FileNames.Count;k++)
                        {                            
                            Filename=FileNames[k].ToString();
                            mailmessage.Attachments.Add(new MailAttachment(Filename));                        
                        }            
                    }
                }
                mailmessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate",);
                mailmessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername",MailUserName);
                mailmessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword",MailPassword);

                
            //向收件人和抄送人循环发送
                for(int j=;j<Receiver.Length;j++)
                {
                    mailmessage.To=Receiver[j].ToString();
                    System.Web.Mail.SmtpMail.SmtpServer="smtp.163.com";
                    try
                    {
                        System.Web.Mail.SmtpMail.Send(mailmessage);
                    }
                    catch(Exception ex)
                    {        
                        Response.Write("<script language='javascript'>alert('邮件发送失败,请您和ustbwuyi联系(QQ:108556024)!')</script>");
                    }
                }
            }

      上面的例子是利用163的SMTP邮件服务器来发送邮件,当然,如果你有自己的邮件服务器更好。

      其次,是利用jmail组件来发送,现在jmail组件的版本很多,在这里我个人推荐jmail4.4pro版本,因为如果你要收邮件的话,必须用pro版本,另外,个人经过测试了其它几个版本,发现只有这个版本不会出现附件丢失的情况,其他几个版本都会出现附件丢失或者损坏的情况,这个对txt文件来说没有影响,但是对于传送图片或者其他的一些压缩文件,会发现从pop服务器上下过来的附件有一些损坏,从而不能正常打开文件。下面是jmail发送邮件的代码。

jmail.MessageClass MyMail = new jmail.MessageClass();

            string SendTos=SendTo.Text.Trim();  //发送人
            string CcTos=CcTo.Text.Trim();      //抄送人
            string[] Receiver=System.Text.RegularExpressions.Regex.Split(SendTos+CcTos,",");  //总收件人
            string FromMail="ustbwuyi1@163.com";//发件人
            string Title="你好"; //邮件主题
            string Body="附件里是重要文档,请查收!";   //邮件主体
            string ShowName="ustbwuyi";//显示名字
            //取email的@前面部分为用户名,即ustbwuyi1,当然也可以自己设置.
            string MailUserName=FromMail.Substring(,FromMail.IndexOf("@"));
            string MailPassword="ustbwuyi";
            if(SendTos!="" || CcTos!="")
            {

                // 字符集
                MyMail.Charset = "GB2312";
                //附件的编码格式
                MyMail.Encoding = "BASE64";
                ////是否将信头编码成iso-8859-1字符集
                     MyMail.ISOEncodeHeaders = false;
                //发送人邮件地址
                MyMail.From = FromMail;
                //发送人姓名
                MyMail.FromName = ShowName;
                // 邮件主题
                MyMail.Subject =Title;
                     //身份验证的用户名
                MyMail.MailServerUserName = MailUserName;
                //用户密码
                MyMail.MailServerPassWord = MailPassword;
                     //邮件内容
                MyMail.Body = Body;
                ArrayList FileNames;
                    //如果存在附件
                    if(FileNames.Count>=)
                    {
                        //添加附件
                        string Filename;
                        for(int k=;k<FileNames.Count;k++)
                        {
                            Filename=FileNames[k].ToString();
                            MyMail.AddAttachment(Filename,false,HttpUtility.UrlDecode(Filename.Substring(Filename.LastIndexOf(".")+,)));
                        }            
                    }

                try
                {
                    //循环发送
                    for(int i=;i<Receiver.Length;i++)
                    {
                        MyMail.AddRecipient(Receiver[i],"","");
                        MyMail.Send("Mail.rshi.cn",false);
                    }
                
            
                }
                catch(Exception ex)
                {
                Response.Write("<script language='javascript'>alert('邮件发送失败,请您和ustbwuyi联系(QQ:108556024)!')</script>");

                }
            }

       好了,现在我们来看看接收邮件的问题。一般来说,接收邮件主要分为两部分,一是将接收到的邮件的信息保存到数据库,如邮件的 主题,内容,发送人,发送时间等。其次是对邮件附件的处理,主要将邮件附件从POP服务器上下载下来并保存到数据库,然后将附件 信息保存到数据库,如附件的路径,附件对应的邮件编号等信息。这一点.NET自带的似乎并不太好处理,没有jmail组件处理方便, 当然关于.NET自带的我并没有深入研究,个人经过比较还是推荐jmail,当然前面说过关于jmail几个版本在这方面的差异,所以个人 还是推荐jmail4.4pro版本。下面是收邮件的代码:

public void ReceiveMails(string Username)
        {
            
            jmail.Message Msg=new jmail.Message();
            jmail.POP3 jpop = new jmail.POP3();
            jmail.Attachments atts;
            jmail.Attachment att;
            
            //username为用户名,该方法通过用户名获取该用户的pop设置,即用户的POP用户名,密码,POP服务器地址以及端口号这四个参数,这四个参数是连接POP服务器的必用参数.
                SqlDataReader dataReader = this.ExtGetSetting(Username);
                if(dataReader.Read())
                {
                    if(dataReader["PopServer"].ToString()!=""&&dataReader["PopUsername"].ToString()!="")
                    {
                        //连接POP服务器
                        jpop.Connect(dataReader["PopUsername"].ToString(),dataReader["PopPassword"].ToString(),dataReader["PopServer"].ToString(),Int32.Parse(dataReader["PopPort"].ToString()));
                        //如果服务器上有邮件
                        if(jpop.Count>=)
                        {
                         for(int i=;i<=jpop.Count;i++)
                            {
                            
                                Msg = jpop.Messages[i];
                                atts=Msg.Attachments;

                             //取数据库中邮件信息中的最大发送时间,即最近接收到的一封邮件的时间
                                Database dbase=new Database();
                                DataTable data=dbase.GetDataTable("select max(MailSendDate) as MailSenderDate from TabMailList where MailTypeFlag='1'");
                                
                             //对服务器上的邮件的发送时间和数据库最近一封邮件的时间进行比较,如果大那么证明该邮件还未被收取,是一封新邮件,这样避免重复收取邮件入库
                                if(Msg.Date>Convert.ToDateTime(data.Rows[][].ToString()))

                                {
                                    //将这封新邮件的信息保存到数据库
                                    this.SaveExtMail(Msg,Username,dataReader["Email"].ToString(),jpop.GetMessageUID(i));
                            
                                    //获取附件上传到服务器并且将信息存入数据库
                                    if(atts.Count>=)
                                    {
                                        for(int k=;k<atts.Count;k++)
                                        {

                                            att=atts[k];//获得附件

                                            string attname=att.Name;
                                            try
                                            {

                                                Random TempNameInt    = new Random(); 
                                                string NewMailDirName  = TempNameInt.Next().ToString();
                                                Directory.CreateDirectory(System.Web.HttpContext.Current.Server.MapPath(".")+"\\AttachFiles\\"+Username+"\\"+NewMailDirName);
                
                                                string mailPath="\\AttachFiles\\"+Username+"\\"+NewMailDirName+"\\"+attname;
            
                                                att.SaveToFile(System.Web.HttpContext.Current.Server.MapPath(".")+mailPath); 
                                                
                                                //获取该封邮件在数据库的ID,以便和附件信息相对应,取邮件表中的最大ID即可 
                                                int mailID=this.GetMailID();
                                               //将附件信息存入数据库
                                                this.AttExtSend(mailID,attname,att.Size,mailPath,Msg.From);
                                            }
                                            catch(Exception ex)
                                            {
                                                throw new Exception(ex.Message);
                                            }
                                        
                                        }
                                    }                                        
                                }                            
                            }                        
                        }    

                        //删除服务器上的邮件
                        jpop.DeleteMessages();
                        //断开连接    
                        jpop.Disconnect();
                    }
                
            }
        }

        至于将邮件信息和附件信息如何存入数据库,就看你自己对表的设计了,我就不多说了,经过上面就可以完全将你POP服务器上的 邮件完全接收到你的本地了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏雪胖纸的玩蛇日常

python3+django2 开发易语言网络验证(中)

41870
来自专栏听雨堂

前后端协调处理checkbox

需求:页面属于一个弹出窗体,查询结果,用checkbox展示,选择后,把选中的结果传递给调用页面。 由于要取得后端写的checkbox控件的值,所以在后端处理最...

25860
来自专栏跟着阿笨一起玩NET

Asp.net中把DataTable或DataGrid导出为Excel

当前编码的一个项目中有把查询结果(显示在DataGrid)导出为excel的需求,尝试了几种方法,作为技巧拿来和大家分享。 内容: 服务器端实现Data...

21610
来自专栏跟着阿笨一起玩NET

ASP.NET中Get和Post的用法

单form的提交有两种方式,一种是get的方法,一种是post 的方法.看下面代码,理解ASP.NET Get和Post两种提交的区别:

40120
来自专栏晓晨的专栏

asp.net mvc 实现上传文件带进度条

41420
来自专栏三杯水

Redis3.2.9/4.0.1集群部署配置优化

http://www.redis.cn/topics/cluster-spec.html

41220
来自专栏智能合约

node.js实现CURL功能

33020
来自专栏更流畅、简洁的软件开发方式

【自然框架】QuickPager分页控件,新增一种分页方式——伪URL分页(Postback版)

适用场景   先说一下伪URL分页的适用场景。在网站的网页里实现查询功能,如果查询条件比较少的话,还比较好办,把查询条件放到URL里面传递即可。但是如果查...

25160
来自专栏小李刀刀的专栏

[译]Laravel 5.0 之自定义错误页面

本文译自 Matt Stauffer 的系列文章. ---- 在以往版本的 Laravel 中,假如你想自定义错误页面——比如当用户访问不存在的页面时显示一张猫...

39550
来自专栏分布式系统和大数据处理

Asp.Net 用户验证(自定义IPrincipal和IIdentity)

前一段时间有两个朋友问我,为什么在HttpModule中无法获得到Session值,因为他们希望自定义一个HttpModule,然后在其中获取Session来进...

24130

扫码关注云+社区

领取腾讯云代金券