|
|
Posted on 2006-05-17 13:11 阿武 阅读(6803) 评论(41) 编辑 收藏 网摘 所属分类: C#ASP.NET常用工具类
一个基于 .NET 2.0 System.Net.Mail namespace 的邮件发送接收组件,参考了以前网上一些基于 System.Web.Mail namespace 例子。
 
 /**//********************************************
*
* description: 基于 .NET 2.0 System.Net.Mail namespace
* 的邮件发送接收组件
*
* author: yyw84
*
* blogs: http://yyw84.cnblogs.com/
*
* Date: 2006-5-4
*
********************************************/

using System;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Threading;
using System.Net.Sockets;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Net.Configuration;
using System.Configuration;

namespace Mailer.Components
  {
 邮件接收类#region 邮件接收类

 /**//// <summary>
/// 邮件接收类
/// </summary>
public class POP3
 {
 Fields#region Fields

string POPServer;
string mPOPUserName;
string mPOPPass;
int mPOPPort;
NetworkStream ns;
StreamReader sr;

#endregion

 Constructors#region Constructors

 /**//// <summary>
/// POP3
/// </summary>
/// <param name="server">POP3服务器名称</param>
/// <param name="userName">用户名</param>
/// <param name="password">用户密码</param>
public POP3(string server, string userName, string password)
: this(server, 110, userName, password)
 {
}

 /**//// <summary>
/// POP3
/// </summary>
/// <param name="server">POP3服务器名称</param>
/// <param name="port">端口号</param>
/// <param name="userName">用户名</param>
/// <param name="password">用户密码</param>
public POP3(string server, int port, string userName, string password)
 {
POPServer = server;
mPOPUserName = userName;
mPOPPass = password;
mPOPPort = port;
}

#endregion

 Methods#region Methods

 Public#region Public

 /**//// <summary>
/// 获得新邮件数量
/// </summary>
/// <returns>新邮件数量</returns>
public int GetNumberOfNewMessages()
 {
byte[] outbytes;
string input;

try
 {
Connect();

input = "stat" + "\r\n";
outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
ns.Write(outbytes, 0, outbytes.Length);
string resp = sr.ReadLine();
 string[] tokens = resp.Split(new Char[] { ' ' });

Disconnect();

return Convert.ToInt32(tokens[1]);
}
catch
 {
return -1;
}
}

 /**//// <summary>
/// 获取新邮件内容
/// </summary>
/// <param name="subj">邮件主题</param>
/// <returns>新邮件内容</returns>
public List<MailMessage> GetNewMessages(string subj)
 {

int newcount;
List<MailMessage> newmsgs = new List<MailMessage>();

try
 {
newcount = GetNumberOfNewMessages();
Connect();

for (int n = 1; n < newcount + 1; n++)
 {
List<string> msglines = GetRawMessage(n);
string msgsubj = GetMessageSubject(msglines);
if (msgsubj.CompareTo(subj) == 0)
 {
MailMessage msg = new MailMessage();
msg.Subject = msgsubj;
msg.From = new MailAddress(GetMessageFrom(msglines));
msg.Body = GetMessageBody(msglines);
newmsgs.Add(msg);
DeleteMessage(n);
}
}

Disconnect();
return newmsgs;
}
catch (Exception e)
 {
return newmsgs;
}
}

 /**//// <summary>
/// 获取新邮件内容
/// </summary>
/// <param name="nIndex">新邮件索引</param>
/// <returns>新邮件内容</returns>
public MailMessage GetNewMessages(int nIndex)
 {
int newcount;
MailMessage msg = new MailMessage();

try
 {
newcount = GetNumberOfNewMessages();
Connect();
int n = nIndex + 1;

if (n < newcount + 1)
 {
List<string> msglines = GetRawMessage(n);
string msgsubj = GetMessageSubject(msglines);


msg.Subject = msgsubj;
msg.From = new MailAddress(GetMessageFrom(msglines));
msg.Body = GetMessageBody(msglines);
}

Disconnect();
return msg;
}
catch
 {
return null;
}
}

#endregion

 Private#region Private

private bool Connect()
 {
TcpClient sender = new TcpClient(POPServer, mPOPPort);
byte[] outbytes;
string input;

try
 {
ns = sender.GetStream();
sr = new StreamReader(ns);

sr.ReadLine();
input = "user " + mPOPUserName + "\r\n";
outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
ns.Write(outbytes, 0, outbytes.Length);
sr.ReadLine();

input = "pass " + mPOPPass + "\r\n";
outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
ns.Write(outbytes, 0, outbytes.Length);
sr.ReadLine();
return true;

}
catch
 {
return false;
}
}

private void Disconnect()
 {
string input = "quit" + "\r\n";
Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
ns.Write(outbytes, 0, outbytes.Length);
ns.Close();
}

private List<string> GetRawMessage(int messagenumber)
 {
Byte[] outbytes;
string input;
string line = "";

input = "retr " + messagenumber.ToString() + "\r\n";
outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
ns.Write(outbytes, 0, outbytes.Length);

List<string> msglines = new List<string>();
do
 {
line = sr.ReadLine();
msglines.Add(line);
} while (line != ".");
msglines.RemoveAt(msglines.Count - 1);

return msglines;
}

private string GetMessageSubject(List<string> msglines)
 {
string[] tokens;
IEnumerator msgenum = msglines.GetEnumerator();
while (msgenum.MoveNext())
 {
string line = (string)msgenum.Current;
if (line.StartsWith("Subject:"))
 {
 tokens = line.Split(new Char[] { ' ' });
return tokens[1].Trim();
}
}
return "None";
}

private string GetMessageFrom(List<string> msglines)
 {
string[] tokens;
IEnumerator msgenum = msglines.GetEnumerator();
while (msgenum.MoveNext())
 {
string line = (string)msgenum.Current;
if (line.StartsWith("From:"))
 {
 tokens = line.Split(new Char[] { '<' });
 return tokens[1].Trim(new Char[] { '<', '>' });
}
}
return "None";
}

private string GetMessageBody(List<string> msglines)
 {
string body = "";
string line = " ";
IEnumerator msgenum = msglines.GetEnumerator();

while (line.CompareTo("") != 0)
 {
msgenum.MoveNext();
line = (string)msgenum.Current;
}

while (msgenum.MoveNext())
 {
body = body + (string)msgenum.Current + "\r\n";
}
return body;
}

private void DeleteMessage(int messagenumber)
 {
Byte[] outbytes;
string input;

try
 {
input = "dele " + messagenumber.ToString() + "\r\n";
outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
ns.Write(outbytes, 0, outbytes.Length);
}
catch (Exception e)
 {
return;
}

}

#endregion

#endregion
}

#endregion

 邮件发送类#region 邮件发送类

public class SMTP
 {
 Fields#region Fields

private string mMailFrom;
private string mMailDisplyName;
private string[] mMailTo;
private string[] mMailCc;
private string[] mMailBcc;
private string mMailSubject;
private string mMailBody;
private string[] mMailAttachments;
private string mSMTPServer;
private int mSMTPPort;
private string mSMTPUsername;
private string mSMTPPassword;
private bool mSMTPSSL;
private MailPriority mPriority = MailPriority.Normal;
private bool mIsBodyHtml = false;
private MailMessage MailObject;
bool mailSent = false;

#endregion

 Properties#region Properties

 /**//// <summary>
/// 发件人地址
/// </summary>
public string MailFrom
 {
 set { mMailFrom = value; }
 get { return mMailFrom; }
}

 /**//// <summary>
/// 显示的名称
/// </summary>
public string MailDisplyName
 {
 set { mMailDisplyName = value; }
 get { return mMailDisplyName; }
}

 /**//// <summary>
/// 收件人地址
/// </summary>
public string[] MailTo
 {
 set { mMailTo = value; }
 get { return mMailTo; }
}

 /**//// <summary>
/// 抄送
/// </summary>
public string[] MailCc
 {
 set { mMailCc = value; }
 get { return mMailCc; }
}

 /**//// <summary>
/// 密件抄送
/// </summary>
public string[] MailBcc
 {
 set { mMailBcc = value; }
 get { return mMailBcc; }
}

 /**//// <summary>
/// 邮件主题
/// </summary>
public string MailSubject
 {
 set { mMailSubject = value; }
 get { return mMailSubject; }
}

 /**//// <summary>
/// 邮件正文
/// </summary>
public string MailBody
 {
 set { mMailBody = value; }
 get { return mMailBody; }
}

 /**//// <summary>
/// 附件
/// </summary>
public string[] MailAttachments
 {
 set { mMailAttachments = value; }
 get { return mMailAttachments; }
}

 /**//// <summary>
/// SMTP 服务器
/// </summary>
public string SMTPServer
 {
 set { mSMTPServer = value; }
 get { return mSMTPServer; }
}

 /**//// <summary>
/// 发送端口号(默认为 25)
/// </summary>
public int SMTPPort
 {
 set { mSMTPPort = value; }
 get { return mSMTPPort; }
}

 /**//// <summary>
/// 用户名
/// </summary>
public string SMTPUsername
 {
 set { mSMTPUsername = value; }
 get { return mSMTPUsername; }
}

 /**//// <summary>
/// 密码
/// </summary>
public string SMTPPassword
 {
 set { mSMTPPassword = value; }
 get { return mSMTPPassword; }
}

 /**//// <summary>
/// 是否使用安全套接字层 (SSL) 加密连接
/// 默认为 false
/// </summary>
public Boolean SMTPSSL
 {
 set { mSMTPSSL = value; }
 get { return mSMTPSSL; }
}

 /**//// <summary>
/// 邮件的优先级
/// </summary>
public MailPriority Priority
 {
 get { return mPriority; }
 set { mPriority = value; }
}

 /**//// <summary>
/// 示邮件正文是否为 Html 格式的值
/// </summary>
public bool IsBodyHtml
 {
 get { return mIsBodyHtml; }
 set { mIsBodyHtml = value; }
}

#endregion

 Constructors#region Constructors

 /**//// <summary>
/// 邮件发送类
/// 主机信息从配置文件中获取
/// 参考:ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.chs/dv_fxgenref/html/54f0f153-17e5-4f49-afdc-deadb940c9c1.htm
/// </summary>
/// <param name="mailFrom">发件人地址</param>
/// <param name="mailTo">收件人地址</param>
/// <param name="mailSubject">邮件主题</param>
/// <param name="mailBody">邮件正文</param>
public SMTP(string[] mailTo, string mailSubject, string mailBody)
 {
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
MailSettingsSectionGroup mailSettings = NetSectionGroup.GetSectionGroup(config).MailSettings;

MailObject = new MailMessage();
mMailFrom = mailSettings.Smtp.From;
mMailDisplyName = mailSettings.Smtp.From;
mMailTo = mailTo;
mMailCc = null;
mMailBcc = null;
mMailSubject = mailSubject;
mMailBody = mailBody;
mMailAttachments = null;
mSMTPServer = mailSettings.Smtp.Network.Host;
mSMTPPort = mailSettings.Smtp.Network.Port;
mSMTPUsername = mailSettings.Smtp.Network.UserName;
mSMTPPassword = mailSettings.Smtp.Network.Password;
mSMTPSSL = false;
}

 /**//// <summary>
/// 邮件发送类
/// </summary>
/// <param name="mailFrom">发件人地址</param>
/// <param name="mailTo">收件人地址</param>
/// <param name="mailSubject">邮件主题</param>
/// <param name="mailBody">邮件正文</param>
/// <param name="smtpServer">SMTP 服务器</param>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
public SMTP(string mailFrom, string[] mailTo, string mailSubject, string mailBody,
string smtpServer, string userName, string password)
: this(mailFrom, mailFrom, mailTo, mailSubject, mailBody, null, smtpServer, userName, password)
 {
}

 /**//// <summary>
/// 邮件发送类
/// </summary>
/// <param name="mailFrom">发件人地址</param>
/// <param name="displayName">显示的名称</param>
/// <param name="mailTo">收件人地址</param>
/// <param name="mailSubject">邮件主题</param>
/// <param name="mailBody">邮件正文</param>
/// <param name="attachments">附件,多个时用逗号隔开(可为空)</param>
/// <param name="smtpServer">SMTP 服务器</param>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
public SMTP(string mailFrom, string[] mailTo, string mailSubject, string mailBody,
string[] attachments, string smtpServer, string userName, string password)
: this(mailFrom, mailFrom, mailTo, mailSubject, mailBody,
attachments, smtpServer, userName, password)
 {
}

 /**//// <summary>
/// 邮件发送类
/// </summary>
/// <param name="mailFrom">发件人地址</param>
/// <param name="displayName">显示的名称</param>
/// <param name="mailTo">收件人地址</param>
/// <param name="mailSubject">邮件主题</param>
/// <param name="mailBody">邮件正文</param>
/// <param name="attachments">附件,多个时用逗号隔开(可为空)</param>
/// <param name="smtpServer">SMTP 服务器</param>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
public SMTP(string mailFrom, string displayName, string[] mailTo, string mailSubject, string mailBody,
string[] attachments, string smtpServer, string userName, string password)
: this(mailFrom, displayName, mailTo, null, null, mailSubject, mailBody,
attachments, smtpServer, 25, userName, password, false)
 {
}

 /**//// <summary>
/// 邮件发送类
/// </summary>
/// <param name="mailFrom">发件人地址</param>
/// <param name="displayName">显示的名称</param>
/// <param name="mailTo">收件人地址</param>
/// <param name="mailCc">抄送,多个收件人用逗号隔开(可为空)</param>
/// <param name="mailBcc">密件抄送,多个收件人用逗号隔开(可为空)</param>
/// <param name="mailSubject">邮件主题</param>
/// <param name="mailBody">邮件正文</param>
/// <param name="attachments">附件,多个时用逗号隔开(可为空)</param>
/// <param name="smtpServer">SMTP 服务器</param>
/// <param name="smtpPort">发送端口号(默认为 25)</param>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
/// <param name="smtpSsl">是否使用安全套接字层 (SSL) 加密连接</param>
public SMTP(string mailFrom, string displayName, string[] mailTo, string[] mailCc, string[] mailBcc, string mailSubject, string mailBody,
string[] attachments, string smtpServer, int smtpPort, string userName, string password, bool smtpSsl)
 {
MailObject = new MailMessage();
mMailFrom = mailFrom;
mMailDisplyName = displayName;
mMailTo = mailTo;
mMailCc = mailCc;
mMailBcc = mailBcc;
mMailSubject = mailSubject;
mMailBody = mailBody;
mMailAttachments = attachments;
mSMTPServer = smtpServer;
mSMTPPort = smtpPort;
mSMTPUsername = userName;
mSMTPPassword = password;
mSMTPSSL = smtpSsl;
}

#endregion

 Methods#region Methods

 /**//// <summary>
/// 同步发送邮件
/// </summary>
/// <returns></returns>
public Boolean Send()
 {
return SendMail(false, null);
}

 /**//// <summary>
/// 异步发送邮件
/// </summary>
/// <param name="userState">异步任务的唯一标识符</param>
/// <returns></returns>
public void SendAsync(object userState)
 {
SendMail(true, userState);
}

 /**//// <summary>
/// 发送邮件
/// </summary>
/// <param name="isAsync">是否异步发送邮件</param>
/// <param name="userState">异步任务的唯一标识符,当 isAsync 为 True 时必须设置该属性, 当 isAsync 为 False 时可设置为 null</param>
/// <returns></returns>
private Boolean SendMail(bool isAsync, object userState)
 {
 设置属性值#region 设置属性值

string[] mailTos = mMailTo;
string[] mailCcs = mMailCc;
string[] mailBccs = mMailBcc;
string[] attachments = mMailAttachments;

// build the email message
MailMessage Email = new MailMessage();
MailAddress MailFrom =
new MailAddress(mMailFrom, mMailDisplyName);
Email.From = MailFrom;

if (mailTos != null)
 {
foreach (string mailto in mailTos)
 {
if (!string.IsNullOrEmpty(mailto))
 {
Email.To.Add(mailto);
}
}
}

if (mailCcs != null)
 {
foreach (string cc in mailCcs)
 {
if (!string.IsNullOrEmpty(cc))
 {
Email.CC.Add(cc);
}
}
}

if (mailBccs != null)
 {
foreach (string bcc in mailBccs)
 {
if (!string.IsNullOrEmpty(bcc))
 {
Email.Bcc.Add(bcc);
}
}
}

if (attachments != null)
 {
foreach (string file in attachments)
 {
if (!string.IsNullOrEmpty(file))
 {
Attachment att = new Attachment(file);
Email.Attachments.Add(att);
}
}
}

Email.Subject = mMailSubject;
Email.Body = mMailBody;
Email.Priority = mPriority;
Email.IsBodyHtml = mIsBodyHtml;

// Smtp Client
SmtpClient SmtpMail =
new SmtpClient(mSMTPServer, mSMTPPort);
SmtpMail.Credentials =
new NetworkCredential(mSMTPUsername, mSMTPPassword);
SmtpMail.EnableSsl = mSMTPSSL;
//SmtpMail.UseDefaultCredentials = false;

SmtpMail.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);

#endregion

try
 {
if (!isAsync)
 {
SmtpMail.Send(Email);
mailSent = true;
}
else
 {
userState = (userState == null) ? Guid.NewGuid() : userState;
SmtpMail.SendAsync(Email, userState);
}
}
catch (SmtpFailedRecipientsException ex)
 {
//System.Windows.Forms.MessageBox.Show(ex.Message);
mailSent = false;
}
catch (Exception ex)
 {
//System.Windows.Forms.MessageBox.Show(ex.Message);
mailSent = false;
}

return mailSent;
}

private void SendCompletedCallback(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
 {
// Get the unique identifier for this asynchronous operation.
String token = (string)e.UserState;

if (e.Cancelled)
 {
Console.WriteLine("[{0}] Send canceled.", token);
mailSent = false;
}
if (e.Error != null)
 {
Console.WriteLine("[{0}] {1}", token, e.Error.ToString());
mailSent = false;
}
else
 {
Console.WriteLine("Message sent.");
mailSent = false;
}

mailSent = true;
}

#endregion
}

#endregion
}

 附加内容#region 附加内容

 POP3 命令简介#region POP3 命令简介

 /**//*

什么是 POP3
POP3 (Post Office Protocol 3) 即邮局协议的第 3 个版本,它规定怎样将个人计算机连接到 Internet 的邮件服务器和下载电子邮件的电子协议。它是因特网电子邮件的 第一个离线协议标准, POP3 允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循 POP3 协议的接收邮件服务器,用来接收电子邮件的。

POP3 命令
POP3 命令包括:
USER username 认证用户名
PASS password 认证密码认证,认证通过则状态转换
APOP name,digest 认可一种安全传输口令的办法,执行成功导致状态转换,请参见 RFC 1321 。
STAT 处理请求 server 回送邮箱统计资料,如邮件数、 邮件总字节数
UIDL n 处理 server 返回用于该指定邮件的唯一标识, 如果没有指定,返回所有的。
LIST n 处理 server 返回指定邮件的大小等
RETR n 处理 server 返回邮件的全部文本
DELE n 处理 server 标记删除,QUIT 命令执行时才真正删除
RSET 处理撤消所有的 DELE 命令
TOP n,m 处理 返回 n 号邮件的前 m 行内容,m 必须是自然数
NOOP 处理 server 返回一个肯定的响应
QUIT 希望结束会话。如果 server 处于"处理" 状态,则现在进入"更新"状态,删除那些标记成删除的邮件。如果 server 处于"认可"状态,则结束会话时 server 不进入"更新"状态 。

使用 telnet 连接 Winmail Server 收信
例如:安装 Winmail 的邮件服务器 IP 是 192.168.0.1(蓝色字体内容由客户端输入,红色字体内容是服务返回的)

telnet 119.119.119.212 110 ----------------------------- 使用 telnet 命令连接服务器 110 端口
Trying 119.119.119.212 ------------------------------ 正在连接服务器 110 端口
Connected to 119.119.119.212. -------------------------- 连接服务器 110 端口成功
+OK Winmail Mail Server POP3 ready
user username ------------------------------------------ 输入用户名, username 为具体的用户名
+OK ---------------------------------------------------- 执行命令成功
pass password ------------------------------------------ 输入用户密码,password 为具体的密码
+OK 2 messages ----------------------------------------- 密码认证通过
(-ERR authorization failed ----------------------------- 密码认证失败)
stat --------------------------------------------------- 邮箱状态
+OK 2 6415 --------------------------------------------- 2 为该信箱总邮件数,6415 为总字节数
list --------------------------------------------------- 列出每封邮件的字节数
+OK ---------------------------------------------------- 执行命令成功,开始显示,左边为邮件的序号,右边为该邮件的大小
1 537 -------------------------------------------------- 第 1 封邮件,大小为 537 字节
2 5878 ------------------------------------------------- 第 2 封邮件,大小为 5878 字节
.
top 1 -------------------------------------------------- 接收第 1 封邮件
+OK ---------------------------------------------------- 接收成功, 返回第 1 封邮件头
Return-Path: <test1@look.com>
Delivered-To: test2@look.com
Received: (winmail server invoked for smtp delivery); Mon, 25 Oct 2004 14:24:27 +0800
From: test1@look.com
To: test2@look.com
Date: Mon, 25 Oct 2004 14:24:27 +0800
Subject: test mail
.
retr 1 ------------------------------------------------- 接收第 1 封邮件
+OK ---------------------------------------------------- 接收成功, 返回第 1 封邮件全部内容
Return-Path: <test1@look.com>
Delivered-To: test2@look.com
Received: (winmail server invoked for smtp delivery); Mon, 25 Oct 2004 14:24:27 +0800
From: test1@look.com
To: test2@look.com
Date: Mon, 25 Oct 2004 14:24:27 +0800
Subject: test mail

Hi, test2
This is a test mail, you don't reply it.

.
dele 1 ------------------------------------------------- 删除第 1 封邮件
+OK ---------------------------------------------------- 删除成功
dele 2 ------------------------------------------------- 删除第 2 封邮件
+OK ---------------------------------------------------- 删除成功
quit --------------------------------------------------- 结束会话
+OK ---------------------------------------------------- 执行命令成功


*/

#endregion

#endregion
测试程序 下载
2006-8-16 最近做的项目需要群发邮件,发现上面的SMTP类每发送一封邮件必须创建创建一个实例,这无疑是对系统资源的浪费,所以重构了一下,结果如下,推荐大家使用下面的实现方法
 
using System;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Threading;
using System.Net.Sockets;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Net.Configuration;
using System.Configuration;

namespace Mailer.Components
  {
 邮件发送类#region 邮件发送类

public class SMTP
 {
 Fields#region Fields

private string _mailFrom;
private string _displayName;
private SmtpClient smtpMail;

#endregion

 Properties#region Properties

public string MailFrom
 {
 get { return _mailFrom; }
 set { _mailFrom = value; }
}

public string DisplayName
 {
 get { return _displayName; }
 set { _displayName = value; }
}

#endregion

 Constructors#region Constructors

public SMTP()
 {
System.Configuration.Configuration config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/");
MailSettingsSectionGroup mailSettings = (MailSettingsSectionGroup)config.GetSectionGroup("system.net/mailSettings");

string mailFrom = mailSettings.Smtp.From;
string smtpServer = mailSettings.Smtp.Network.Host;
int smtpPort = mailSettings.Smtp.Network.Port;
string smtpUsername = mailSettings.Smtp.Network.UserName;
string password = mailSettings.Smtp.Network.Password;

smtpMail = new SmtpClient(smtpServer, smtpPort);
smtpMail.Credentials = new NetworkCredential(smtpUsername, password);
this._mailFrom = mailFrom;
this._displayName = smtpUsername;
}

public SMTP(string smtpServer, string userName, string password)
: this(null, smtpServer, userName, password)
 {
}

 /**//// <summary>
/// 邮件发送类
/// </summary>
/// <param name="mailFrom">发件人地址</param>
/// <param name="smtpServer">SMTP 服务器</param>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
public SMTP(string mailFrom, string smtpServer, string userName, string password)
: this(mailFrom, mailFrom, smtpServer, userName, password)
 {

}

 /**//// <summary>
/// 邮件发送类
/// </summary>
/// <param name="mailFrom">发件人地址</param>
/// <param name="displayName">显示的名称</param>
/// <param name="smtpServer">SMTP 服务器</param>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
public SMTP(string mailFrom, string displayName, string smtpServer, string userName, string password)
: this(mailFrom, displayName, smtpServer, 25, userName, password, false)
 {
}

public SMTP(string mailFrom, string displayName, string smtpServer, int smtpPort, string userName, string password, bool smtpSsl)
 {
this._mailFrom = mailFrom;
this._displayName = displayName;
smtpMail = new SmtpClient(smtpServer, smtpPort);
smtpMail.Credentials = new NetworkCredential(userName, password);
smtpMail.EnableSsl = smtpSsl;
}


#endregion

 Methods#region Methods

 Public#region Public

public Boolean Send(string mailTo, string mailSubject, string mailBody, MailPriority priority, bool isBodyHtml)
 {
 string[] mailTos = new string[] { mailTo };
string[] attachments = null;
System.Text.Encoding bodyEncoding = System.Text.Encoding.Default;
return Send(mailTos, null, null, mailSubject, mailBody, attachments, priority, isBodyHtml, bodyEncoding);
}

public Boolean Send(string mailTo, string mailSubject, string mailBody, string[] attachments, MailPriority priority, bool isBodyHtml, System.Text.Encoding bodyEncoding)
 {
 string[] mailTos = new string[] { mailTo };
return Send(mailTos, null, null, mailSubject, mailBody, attachments, priority, isBodyHtml, bodyEncoding);
}

public Boolean Send(string[] mailTos, string[] mailCcs, string[] mailBccs, string mailSubject, string mailBody, string[] attachments, MailPriority priority, bool isBodyHtml, System.Text.Encoding bodyEncoding)
 {
return Send(this._mailFrom, this._displayName, mailTos, mailCcs, mailBccs, mailSubject, mailBody, attachments, priority, isBodyHtml, bodyEncoding);
}

 /**//// <summary>
/// 同步发送邮件
/// </summary>
/// <returns></returns>
public Boolean Send(string mailFrom, string displayName, string[] mailTos, string[] mailCcs, string[] mailBccs, string mailSubject, string mailBody, string[] attachments, MailPriority priority, bool isBodyHtml, System.Text.Encoding bodyEncoding)
 {
return SendMail(false, null, mailFrom, displayName, mailTos, mailCcs, mailBccs, mailSubject, mailBody, attachments, priority, isBodyHtml, bodyEncoding);
}

public void SendAsync(object userState, string mailTo, string mailSubject, string mailBody, MailPriority priority, bool isBodyHtml)
 {
 string[] mailTos = new string[] { mailTo };
string[] attachments = null;
System.Text.Encoding bodyEncoding = System.Text.Encoding.Default;
SendAsync(userState, mailTos, null, null, mailSubject, mailBody, attachments, priority, isBodyHtml, bodyEncoding);
}

public void SendAsync(object userState, string mailTo, string mailSubject, string mailBody, string[] attachments, MailPriority priority, bool isBodyHtml, System.Text.Encoding bodyEncoding)
 {
 string[] mailTos = new string[] { mailTo };
SendAsync(userState, this._mailFrom, this._displayName, mailTos, null, null, mailSubject, mailBody, attachments, priority, isBodyHtml, bodyEncoding);
}

public void SendAsync(object userState, string mailFrom, string displayName, string[] mailTos, string[] mailCcs, string[] mailBccs, string mailSubject, string mailBody, string[] attachments, MailPriority priority, bool isBodyHtml, System.Text.Encoding bodyEncoding)
 {
SendMail(true, userState, mailFrom, displayName, mailTos, mailCcs, mailBccs, mailSubject, mailBody, attachments, priority, isBodyHtml, bodyEncoding);
}

 /**//// <summary>
/// 异步发送邮件
/// </summary>
/// <param name="userState">异步任务的唯一标识符</param>
/// <returns></returns>
public void SendAsync(object userState, string[] mailTos, string[] mailCcs, string[] mailBccs, string mailSubject, string mailBody, string[] attachments, MailPriority priority, bool isBodyHtml, System.Text.Encoding bodyEncoding)
 {
SendMail(true, userState, null, null, mailTos, mailCcs, mailBccs, mailSubject, mailBody, attachments, priority, isBodyHtml, bodyEncoding);
}


 /**//// <summary>
/// 发送邮件
/// </summary>
/// <param name="isAsync">是否异步发送邮件</param>
/// <param name="userState">异步任务的唯一标识符,当 isAsync 为 True 时必须设置该属性, 当 isAsync 为 False 时可设置为 null</param>
/// <returns></returns>
private Boolean SendMail(bool isAsync, object userState, string mailFrom, string displayName, string[] mailTos, string[] mailCcs, string[] mailBccs, string mailSubject, string mailBody, string[] attachments, MailPriority priority, bool isBodyHtml, System.Text.Encoding bodyEncoding)
 {
bool mailSent = false;

 设置属性值#region 设置属性值

if (string.IsNullOrEmpty(mailFrom))
mailFrom = this._mailFrom;

if (string.IsNullOrEmpty(displayName))
displayName = this._displayName;

MailMessage Email = GetMailMessage(mailFrom, displayName, mailTos, mailCcs, mailBccs, mailSubject, mailBody, attachments, priority, isBodyHtml, bodyEncoding);

smtpMail.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);

#endregion

try
 {
if (!isAsync)
 {
smtpMail.Send(Email);
mailSent = true;
}
else
 {
userState = (userState == null) ? Guid.NewGuid() : userState;
smtpMail.SendAsync(Email, userState);
}
}
catch (SmtpFailedRecipientsException ex)
 {
//System.Windows.Forms.MessageBox.Show(ex.Message);
mailSent = false;
}
catch (Exception ex)
 {
//System.Windows.Forms.MessageBox.Show(ex.Message);
mailSent = false;
}

return mailSent;
}

#endregion

 Private#region Private

private MailMessage GetMailMessage(string mailFrom, string displayName, string[] mailTos, string[] mailCcs, string[] mailBccs, string mailSubject, string mailBody, string[] attachments, MailPriority priority, bool isBodyHtml, System.Text.Encoding bodyEncoding)
 {
// build the email message
MailMessage emailMessage = new MailMessage();

if (string.IsNullOrEmpty(mailFrom))
mailFrom = this._mailFrom;

if (string.IsNullOrEmpty(displayName))
displayName = this._displayName;

MailAddress mailFromObject = new MailAddress(mailFrom, displayName);

emailMessage.From = mailFromObject;

if (mailTos != null)
 {
foreach (string mailto in mailTos)
 {
if (!string.IsNullOrEmpty(mailto))
 {
emailMessage.To.Add(mailto);
}
}
}

if (mailCcs != null)
 {
foreach (string cc in mailCcs)
 {
if (!string.IsNullOrEmpty(cc))
 {
emailMessage.CC.Add(cc);
}
}
}

if (mailBccs != null)
 {
foreach (string bcc in mailBccs)
 {
if (!string.IsNullOrEmpty(bcc))
 {
emailMessage.Bcc.Add(bcc);
}
}
}

if (attachments != null)
 {
foreach (string file in attachments)
 {
if (!string.IsNullOrEmpty(file))
 {
Attachment att = new Attachment(file);
emailMessage.Attachments.Add(att);
}
}
}

emailMessage.Subject = mailSubject;
emailMessage.Body = mailBody;
emailMessage.Priority = priority;
emailMessage.IsBodyHtml = isBodyHtml;
emailMessage.BodyEncoding = bodyEncoding;

return emailMessage;
}

private void SendCompletedCallback(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
 {
bool mailSent = false;

// Get the unique identifier for this asynchronous operation.
String token = e.UserState.ToString();

if (e.Cancelled)
 {
//Console.WriteLine("[{0}] Send canceled.", token);
mailSent = false;
}
if (e.Error != null)
 {
//Console.WriteLine("[{0}] {1}", token, e.Error.ToString());
mailSent = false;
}
else
 {
//Console.WriteLine("Message sent.");
mailSent = false;
}

mailSent = true;
}

#endregion

#endregion
}

#endregion
}
Feedback
@cdlkjds
源码大部分来自网上,其实我只是给它稍加了修改,添加了一些自己的东西 :)
感谢所有无私奉献的同志们
运行后发现:
如果我的邮箱服务器是不需要验证用户名密码就可以登录的,那输入的用户密码为空,则不能发送成功。
还有想问问这个组件里的 Mailer中的Constructors中的构造函数里,发件人的信息是从配置文件里读的,
NetSectionGroup.GetSectionGroup(config).MailSettings 这句是读取config中的MailSettings配置节的信息,可是config文件中并没有哪个section的name是MailSettings 啊 请问下这个是从哪里读出来的啊?
我运行代码,不能断点调试,所以也找不出是从哪里读出来的,还望多多赐教
config文件中
<system.net>
<mailSettings>
<!-- these settings define the mail server settings
from: the user name from which the email is sent - this is the application that is sending the message
host: the name of your mail server
userName: the name the application will use to log into the mail server
password: the password for the above user name
-->
<smtp from="admin@your-domain.com">
<network host="your-mail-server-name"
userName="your-user-name"
password="your-password" />
</smtp>
</mailSettings>
</system.net>
@yyy
能说明一定具体情况吗?是不是设置了断点后是一个空心的圆圈,里面有一个感叹号,记得以前遇到过这种情况,你重新生成解决方案试试
异步发送是什么意思,能返回什么状态吗?
SmtpMail.SendAsync(Email, userState);
|