1. Introduction
This mail library is an extension of SocketHelper
which is described in my previous article.
No CDO needed and no System.Web.Mail
which is a package to CDO needed.
Now, let's see what is inside.
2. Classes
MailMessage
SmtpServer
MailMessage
is used for storing mail messages (currently doesn't support attachments).
SmtpServer
is a class to communicate with SMTP servers, inside which there is a SocketHelper
(with some updates, download source code for detail).
3. Code Detail
The class MailMessage
:
public class MailMessage
{
public enum BodyFormat
{
HTML,TEXT
}
private string sFrom;
private string sTo;
private string sCc;
private string sSubject;
private BodyFormat bfFormat=BodyFormat.TEXT;
private string sBody;
private string sFromName;
private string sToName;
public string Cc
{
get
{
return sCc;
}
set
{
sCc=value;
}
}
public string FromName
{
get
{
if(sFromName==null || sFromName=="")
sFromName=sFrom;
return sFromName;
}
set
{
sFromName=value;
}
}
public string ToName
{
get
{
if(sToName==null || sToName=="")
sToName=sTo;
return sToName;
}
set
{
sToName=value;
}
}
public string From
{
get
{
return sFrom;
}
set
{
sFrom=value;
}
}
public string To
{
get
{
return sTo;
}
set
{
sTo=value;
}
}
public string Subject
{
get
{
return sSubject;
}
set
{
sSubject=value;
}
}
public string Body
{
get
{
return sBody;
}
set
{
sBody=value;
}
}
public BodyFormat MailFormat
{
get
{
return bfFormat;
}
set
{
bfFormat=value;
}
}
public MailMessage()
{
}
public override string ToString()
{
StringBuilder sb=new StringBuilder();
sb.AppendFormat("From: {0}\r\n",this.FromName);
sb.AppendFormat("To: {0}\r\n",this.ToName);
if(this.Cc!=null && this.Cc!="")
{
sb.AppendFormat("Cc: {0}\r\n",this.Cc.Replace(";",","));
}
sb.AppendFormat("Date: {0}\r\n",
DateTime.Now.ToString("ddd, d M y H:m:s z"));
sb.AppendFormat("Subject: {0}\r\n",this.Subject);
sb.AppendFormat("X-Mailer: vmlinux.Net.Mail.SmtpServer\r\n");
switch(this.MailFormat)
{
case BodyFormat.TEXT:
sb.AppendFormat("Content-type:text/plain;Charset=GB2312\r\n");
break;
case BodyFormat.HTML:
sb.AppendFormat("Content-type:text/html;Charset=GB2312\r\n");
break;
default:
break;
}
sb.AppendFormat("\r\n{0}\r\n",this.Body);
return sb.ToString();
}
}
I get all the message inside mail through the method ToString()
.
Now, the following is class SmtpServer
:
public class SmtpServer
{
private string sServer;
private int iPort;
private bool bAuth=false;
private string sUser;
private string sPass;
private StringBuilder sbLog=null;
private bool bLog=true;
private SocketHelper helper=null;
private TalkState state=TalkState.WaitInit;
public enum TalkState
{
WaitInit,Initialized,SignedIn,LoginFailed,Ended
}
protected SocketHelper Helper
{
get
{
if(helper==null)
helper=new SocketHelper(this.Server,this.Port);
return helper;
}
}
public bool LogEvent
{
get
{
return bLog;
}
set
{
bLog=value;
}
}
public string LogMessage
{
get
{
if(this.LogEvent)
return sbLog.ToString();
else
return "";
}
}
public string Server
{
get
{
return sServer;
}
set
{
sServer=value;
}
}
public int Port
{
get
{
return iPort;
}
set
{
iPort=value;
}
}
public bool RequireAuthorization
{
get
{
return bAuth;
}
set
{
bAuth=value;
}
}
public string AuthUser
{
get
{
return sUser;
}
set
{
sUser=value;
}
}
public string AuthPass
{
get
{
return sPass;
}
set
{
sPass=value;
}
}
public SmtpServer()
{
}
public void Init()
{
Log(helper.GetFullResponse());
Helper.SendCommand("EHLO "+this.Server);
Log(Helper.GetFullResponse());
state=TalkState.Initialized;
}
public bool Login()
{
if(this.RequireAuthorization)
{
Helper.SendCommand("AUTH LOGIN");
Log(Helper.GetFullResponse());
Helper.SendCommand(
Convert.ToBase64String(
Encoding.Default.GetBytes(this.AuthUser)));
Log(Helper.GetFullResponse());
Helper.SendCommand(
Convert.ToBase64String(
Encoding.Default.GetBytes(this.AuthPass)));
Log(Helper.GetFullResponse());
if(Helper.GetResponseState()==235)
{
state=TalkState.SignedIn;
return true;
}
else
{
state=TalkState.LoginFailed;
return false;
}
}
else
{
state=TalkState.SignedIn;
return true;
}
}
public void SendKeep(MailMessage msg)
{
if((state==TalkState.Initialized &&
!this.RequireAuthorization) || state==TalkState.SignedIn)
{
Helper.SendCommand("MAIL From:"+msg.From);
Log(Helper.GetFullResponse());
Helper.SendCommand("RCPT To:"+msg.To);
Log(Helper.GetFullResponse());
Helper.SendCommand("DATA");
Log(Helper.GetFullResponse());
Helper.SendData(Encoding.Default.GetBytes(msg.ToString()));
Helper.SendCommand(".");
Log(Helper.GetFullResponse());
}
}
public void Quit()
{
Helper.SendCommand("QUIT");
Helper.Close();
state=TalkState.Ended;
}
public bool Send(MailMessage msg)
{
if(state==TalkState.Ended)
return false;
Log(Helper.GetFullResponse());
Helper.SendCommand("EHLO "+this.Server);
Log(Helper.GetFullResponse());
if(this.RequireAuthorization)
{
Helper.SendCommand("AUTH LOGIN");
Log(Helper.GetFullResponse());
Helper.SendCommand(
Convert.ToBase64String(
Encoding.Default.GetBytes(this.AuthUser)));
Log(Helper.GetFullResponse());
Helper.SendCommand(
Convert.ToBase64String(
Encoding.Default.GetBytes(this.AuthPass)));
Log(Helper.GetFullResponse());
if(Helper.GetResponseState()!=235)
{
Helper.SendCommand("QUIT");
Helper.Close();
state=TalkState.Ended;
return false;
}
}
Helper.SendCommand("MAIL From:"+msg.From);
Log(Helper.GetFullResponse());
Helper.SendCommand("RCPT To:"+msg.To);
Log(Helper.GetFullResponse());
Helper.SendCommand("DATA");
Log(Helper.GetFullResponse());
Helper.SendData(Encoding.Default.GetBytes(msg.ToString()));
Helper.SendCommand(".");
Log(Helper.GetFullResponse());
Helper.SendCommand("QUIT");
Helper.Close();
state=TalkState.Ended;
return true;
}
private void Log(string msg)
{
if(this.LogEvent)
{
if(sbLog==null)
sbLog=new StringBuilder();
sbLog.AppendFormat("{0}\r\n",msg);
}
}
}
You can send multiple emails in one connection or simply send one.
To send multiple emails, follow this command sequence:
Init
--- to receive server response and say hello.
Login
--- if the server requires user login.
SendKeep
--- send mail and keep connection.
- ... --- more mail through
SendKeep
.
Quit
--- say good bye to server.
If you are sending only one mail in one connection, simply call Send
.
So that's it.
4. TODO
- error handling
- attachments
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.