|
Hello there and thanks so much for an excellent class, it really set me on the right path for a bulk mailer i'm writing (dont worry its not spam!!).
Only hassle was bounce removal, for this i only needer the headers so i've added another function "GetEmailHeader".
Maybe a ne release with this functionality would be a good idea. Added the code but anyone wants to email then please ask me. stephen.adam@gmail.com
<br />
<br />
using System;<br />
using System.Collections.Generic;<br />
using System.IO;<br />
using System.Net;<br />
using System.Net.Sockets;<br />
using System.Net.Security;<br />
using System.Text;<br />
<br />
namespace DiscoveryMassMailer.Resources{<br />
<br />
namespace Pop3 {<br />
<br />
public struct EmailUid {<br />
public int EmailId;<br />
public string Uid;<br />
<br />
public EmailUid(int EmailId, string Uid) {<br />
this.EmailId = EmailId;<br />
this.Uid = Uid;<br />
}<br />
}<br />
<br />
<br />
public class Pop3Exception:ApplicationException {<br />
public Pop3Exception() { }<br />
public Pop3Exception(string ErrorMessage) : base(ErrorMessage) { }<br />
}<br />
<br />
<br />
public enum Pop3ConnectionStateEnum {<br />
None=0,<br />
Disconnected,<br />
Authorization,<br />
Connected,<br />
Closed<br />
}<br />
<br />
<br />
<br />
public delegate void WarningHandler(string WarningText, string Response);<br />
<br />
<br />
public delegate void TraceHandler(string TraceText);<br />
<br />
<br />
<br />
public class Pop3MailClient {<br />
<br />
<br />
public event WarningHandler Warning;<br />
<br />
protected void CallWarning(string methodName, string response, string warningText, params object[] warningParameters) {<br />
warningText = string.Format(warningText, warningParameters);<br />
if (Warning!=null) {<br />
Warning(methodName + ": " + warningText, response);<br />
}<br />
CallTrace("!! {0}", warningText);<br />
}<br />
<br />
<br />
public event TraceHandler Trace;<br />
<br />
protected void CallTrace(string text, params object[] parameters) {<br />
if (Trace!=null) {<br />
Trace(DateTime.Now.ToString("hh:mm:ss ") + popServer + " " + string.Format(text, parameters));<br />
}<br />
}<br />
<br />
protected void TraceFrom(string text, params object[] parameters) {<br />
if (Trace!=null) {<br />
CallTrace(" " + string.Format(text, parameters));<br />
}<br />
}<br />
<br />
<br />
<br />
public string PopServer {<br />
get { return popServer; }<br />
}<br />
protected string popServer;<br />
<br />
<br />
public int Port {<br />
get { return port; }<br />
}<br />
protected int port;<br />
<br />
<br />
public bool UseSSL {<br />
get { return useSSL; }<br />
}<br />
private bool useSSL;<br />
<br />
<br />
public bool IsAutoReconnect {<br />
get { return isAutoReconnect; }<br />
set { isAutoReconnect = value; }<br />
}<br />
private bool isAutoReconnect = false;<br />
private bool isTimeoutReconnect = false;<br />
<br />
<br />
<br />
public int ReadTimeout {<br />
get { return readTimeout; }<br />
set {<br />
readTimeout = value;<br />
if (pop3Stream!=null && pop3Stream.CanTimeout) {<br />
pop3Stream.ReadTimeout = readTimeout;<br />
}<br />
}<br />
}<br />
protected int readTimeout = -1;<br />
<br />
<br />
public string Username {<br />
get { return username; }<br />
}<br />
protected string username;<br />
<br />
<br />
public string Password {<br />
get { return password; }<br />
}<br />
protected string password;<br />
<br />
<br />
public Pop3ConnectionStateEnum Pop3ConnectionState {<br />
get { return pop3ConnectionState; }<br />
}<br />
protected Pop3ConnectionStateEnum pop3ConnectionState = Pop3ConnectionStateEnum.Disconnected;<br />
<br />
<br />
<br />
protected void setPop3ConnectionState(Pop3ConnectionStateEnum State) {<br />
pop3ConnectionState = State;<br />
CallTrace(" Pop3MailClient Connection State {0} reached", State);<br />
}<br />
<br />
protected void EnsureState(Pop3ConnectionStateEnum requiredState) {<br />
if (pop3ConnectionState!=requiredState) {<br />
throw new Pop3Exception("GetMailboxStats only accepted during connection state: " + requiredState.ToString() + <br />
"\n The connection to server "+ popServer + " is in state " + pop3ConnectionState.ToString());<br />
}<br />
}<br />
<br />
<br />
private TcpClient serverTcpConnection;<br />
private Stream pop3Stream;<br />
protected StreamReader pop3StreamReader;<br />
protected string CRLF = "\r\n";<br />
<br />
<br />
<br />
public Pop3MailClient(string PopServer, int Port, bool useSSL, string Username, string Password) {<br />
this.popServer = PopServer;<br />
this.port = Port;<br />
this.useSSL = useSSL;<br />
this.username = Username;<br />
this.password = Password;<br />
}<br />
<br />
<br />
public void Connect() {<br />
if (pop3ConnectionState!=Pop3ConnectionStateEnum.Disconnected &&<br />
pop3ConnectionState!=Pop3ConnectionStateEnum.Closed && <br />
!isTimeoutReconnect) {<br />
CallWarning("connect", "", "Connect command received, but connection state is: " + pop3ConnectionState.ToString());<br />
} else {<br />
try {<br />
CallTrace(" Connect at port {0}", port);<br />
serverTcpConnection = new TcpClient(popServer, port);<br />
} catch (Exception ex) {<br />
throw new Pop3Exception("Connection to server "+ popServer + ", port " + port + " failed.\nRuntime Error: "+ex.ToString());<br />
}<br />
<br />
if (useSSL) {<br />
try {<br />
CallTrace(" Get SSL connection");<br />
pop3Stream = new SslStream(serverTcpConnection.GetStream(), false);<br />
pop3Stream.ReadTimeout = readTimeout;<br />
} catch (Exception ex) {<br />
throw new Pop3Exception("Server " + popServer + " found, but cannot get SSL data stream.\nRuntime Error: "+ex.ToString());<br />
}<br />
<br />
try {<br />
CallTrace(" Get SSL authentication");<br />
((SslStream)pop3Stream).AuthenticateAsClient(popServer);<br />
} catch (Exception ex) {<br />
throw new Pop3Exception("Server " + popServer + " found, but problem with SSL Authentication.\nRuntime Error: " + ex.ToString());<br />
}<br />
} else {<br />
try {<br />
CallTrace(" Get connection without SSL");<br />
pop3Stream = serverTcpConnection.GetStream();<br />
pop3Stream.ReadTimeout = readTimeout;<br />
} catch (Exception ex) {<br />
throw new Pop3Exception("Server " + popServer + " found, but cannot get data stream (without SSL).\nRuntime Error: "+ex.ToString());<br />
}<br />
}<br />
try {<br />
pop3StreamReader= new StreamReader(pop3Stream, Encoding.ASCII);<br />
} catch (Exception ex) {<br />
if (useSSL) {<br />
throw new Pop3Exception("Server " + popServer + " found, but cannot read from SSL stream.\nRuntime Error: " + ex.ToString());<br />
} else {<br />
throw new Pop3Exception("Server " + popServer + " found, but cannot read from stream (without SSL).\nRuntime Error: " + ex.ToString());<br />
}<br />
}<br />
<br />
string response;<br />
if (!readSingleLine(out response)) {<br />
throw new Pop3Exception("Server " + popServer + " not ready to start AUTHORIZATION.\nMessage: " + response);<br />
}<br />
setPop3ConnectionState(Pop3ConnectionStateEnum.Authorization);<br />
<br />
if (!executeCommand("USER "+ username, out response)) {<br />
throw new Pop3Exception("Server " + popServer + " doesn't accept username '" + username + "'.\nMessage: " + response);<br />
}<br />
<br />
if (!executeCommand("PASS " + password, out response)) {<br />
throw new Pop3Exception("Server " + popServer + " doesn't accept password '" + password + "' for user '" + username + "'.\nMessage: " + response);<br />
}<br />
<br />
setPop3ConnectionState(Pop3ConnectionStateEnum.Connected);<br />
}<br />
}<br />
<br />
<br />
public void Disconnect() {<br />
if (pop3ConnectionState==Pop3ConnectionStateEnum.Disconnected ||<br />
pop3ConnectionState==Pop3ConnectionStateEnum.Closed) {<br />
CallWarning("disconnect", "", "Disconnect received, but was already disconnected.");<br />
} else {<br />
try {<br />
string response;<br />
if (executeCommand("QUIT", out response)) {<br />
setPop3ConnectionState(Pop3ConnectionStateEnum.Closed);<br />
} else {<br />
CallWarning("Disconnect", response, "negative response from server while closing connection: " + response);<br />
setPop3ConnectionState(Pop3ConnectionStateEnum.Disconnected);<br />
}<br />
} finally {<br />
if (pop3Stream!=null) {<br />
pop3Stream.Close();<br />
}<br />
<br />
pop3StreamReader.Close();<br />
}<br />
}<br />
}<br />
<br />
<br />
public bool DeleteEmail(int msg_number) {<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
string response;<br />
if (!executeCommand("DELE " + msg_number.ToString(), out response)) {<br />
CallWarning("DeleteEmail", response, "negative response for email (Id: {0}) delete request", msg_number);<br />
return false;<br />
}<br />
return true;<br />
}<br />
<br />
<br />
public bool GetEmailIdList(out List<int> EmailIds) {<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
EmailIds = new List<int>();<br />
<br />
string response;<br />
if (!executeCommand("LIST", out response)) {<br />
CallWarning("GetEmailIdList", response, "negative response for email list request");<br />
return false;<br />
}<br />
<br />
int EmailId;<br />
while (readMultiLine(out response)) {<br />
if (int.TryParse(response.Split(' ')[0], out EmailId)) {<br />
EmailIds.Add(EmailId);<br />
} else {<br />
CallWarning("GetEmailIdList", response, "first characters should be integer (EmailId)");<br />
}<br />
}<br />
TraceFrom("{0} email ids received", EmailIds.Count);<br />
return true;<br />
}<br />
<br />
<br />
public int GetEmailSize(int msg_number) {<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
string response;<br />
executeCommand("LIST " + msg_number.ToString(), out response);<br />
int EmailSize = 0;<br />
string[] responseSplit = response.Split(' ');<br />
if (responseSplit.Length<2 || !int.TryParse(responseSplit[2], out EmailSize)) {<br />
CallWarning("GetEmailSize", response, "'+OK int int' format expected (EmailId, EmailSize)");<br />
}<br />
<br />
return EmailSize;<br />
}<br />
<br />
<br />
public bool GetUniqueEmailIdList(out List<EmailUid> EmailIds) {<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
EmailIds = new List<EmailUid>();<br />
<br />
string response;<br />
if (!executeCommand("UIDL ", out response)) {<br />
CallWarning("GetUniqueEmailIdList", response, "negative response for email list request");<br />
return false;<br />
}<br />
<br />
int EmailId;<br />
while (readMultiLine(out response)) {<br />
string[] responseSplit = response.Split(' ');<br />
if (responseSplit.Length<2) {<br />
CallWarning("GetUniqueEmailIdList", response, "response not in format 'int string'");<br />
} else if (!int.TryParse(responseSplit[0], out EmailId)) {<br />
CallWarning("GetUniqueEmailIdList", response, "first charaters should be integer (Unique EmailId)");<br />
} else {<br />
EmailIds.Add(new EmailUid(EmailId, responseSplit[1]));<br />
}<br />
}<br />
TraceFrom("{0} unique email ids received", EmailIds.Count);<br />
return true;<br />
}<br />
<br />
<br />
public bool GetUniqueEmailIdList(out SortedList<string, int> EmailIds) {<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
EmailIds = new SortedList<string, int>();<br />
<br />
string response;<br />
if (!executeCommand("UIDL", out response)) {<br />
CallWarning("GetUniqueEmailIdList", response, "negative response for email list request");<br />
return false;<br />
}<br />
<br />
int EmailId;<br />
while (readMultiLine(out response)) {<br />
string[] responseSplit = response.Split(' ');<br />
if (responseSplit.Length<2) {<br />
CallWarning("GetUniqueEmailIdList", response, "response not in format 'int string'");<br />
} else if (!int.TryParse(responseSplit[0], out EmailId)) {<br />
CallWarning("GetUniqueEmailIdList", response, "first charaters should be integer (Unique EmailId)");<br />
} else {<br />
EmailIds.Add(responseSplit[1], EmailId);<br />
}<br />
}<br />
TraceFrom("{0} unique email ids received", EmailIds.Count);<br />
return true;<br />
}<br />
<br />
<br />
public int GetUniqueEmailId(EmailUid msg_number) {<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
string response;<br />
executeCommand("LIST " + msg_number.ToString(), out response);<br />
int EmailSize = 0;<br />
string[] responseSplit = response.Split(' ');<br />
if (responseSplit.Length<2 || !int.TryParse(responseSplit[2], out EmailSize)) {<br />
CallWarning("GetEmailSize", response, "'+OK int int' format expected (EmailId, EmailSize)");<br />
}<br />
<br />
return EmailSize;<br />
}<br />
<br />
<br />
public bool NOOP() {<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
string response;<br />
if (!executeCommand("NOOP", out response)) {<br />
CallWarning("NOOP", response, "negative response for NOOP request");<br />
return false;<br />
}<br />
return true;<br />
}<br />
<br />
protected bool isTraceRawEmail = false;<br />
<br />
<br />
protected StringBuilder RawEmailSB;<br />
<br />
<br />
public bool GetRawEmail(int MessageNo, out string EmailText) {<br />
if (!SendRetrCommand(MessageNo)) {<br />
EmailText = null;<br />
return false;<br />
}<br />
<br />
string response;<br />
int LineCounter = 0;<br />
if (RawEmailSB==null) {<br />
RawEmailSB = new StringBuilder(100000);<br />
} else {<br />
RawEmailSB.Length = 0;<br />
}<br />
isTraceRawEmail = true;<br />
while (readMultiLine(out response)) {<br />
LineCounter += 1;<br />
}<br />
EmailText = RawEmailSB.ToString();<br />
TraceFrom("email with {0} lines, {1} chars received", LineCounter.ToString(), EmailText.Length);<br />
return true;<br />
}<br />
<br />
<br />
public bool GetEmailHeader(int MessageNo, out string EmailHeader)<br />
{<br />
if (!SendTopCommand(MessageNo))<br />
{<br />
EmailHeader = null;<br />
return false;<br />
}<br />
<br />
string response;<br />
int LineCounter = 0;<br />
if (RawEmailSB == null)<br />
{<br />
RawEmailSB = new StringBuilder(100000);<br />
}<br />
else<br />
{<br />
RawEmailSB.Length = 0;<br />
}<br />
isTraceRawEmail = true;<br />
while (readMultiLine(out response))<br />
{<br />
LineCounter += 1;<br />
}<br />
EmailHeader = RawEmailSB.ToString();<br />
TraceFrom("email with {0} lines, {1} chars received", LineCounter.ToString(), EmailHeader.Length);<br />
return true;<br />
}<br />
<br />
<br />
<br />
<br />
public bool UndeleteAllEmails() {<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
string response;<br />
return executeCommand("RSET", out response);<br />
}<br />
<br />
<br />
public bool GetMailboxStats(out int NumberOfMails, out int MailboxSize) {<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
<br />
string response;<br />
NumberOfMails = 0;<br />
MailboxSize =0;<br />
if (executeCommand("STAT", out response)) {<br />
string[] responseParts = response.Split(' ');<br />
if (responseParts.Length<2) {<br />
throw new Pop3Exception("Server " + popServer + " sends illegally formatted response." +<br />
"\nExpected format: +OK int int" +<br />
"\nReceived response: " + response);<br />
}<br />
NumberOfMails = int.Parse(responseParts[1]);<br />
MailboxSize = int.Parse(responseParts[2]);<br />
return true;<br />
}<br />
return false;<br />
}<br />
<br />
<br />
protected bool SendRetrCommand(int MessageNo) {<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
string response;<br />
if (!executeCommand("RETR "+ MessageNo.ToString(), out response)) {<br />
CallWarning("GetRawEmail", response, "negative response for email (ID: {0}) request", MessageNo);<br />
return false;<br />
}<br />
return true;<br />
}<br />
<br />
protected bool SendTopCommand(int MessageNo)<br />
{<br />
EnsureState(Pop3ConnectionStateEnum.Connected);<br />
string response;<br />
if (!executeCommand("TOP "+MessageNo.ToString()+" 0", out response))<br />
{<br />
CallWarning("GetEmailHeader", response, "negative response for email (ID: {0}) request", MessageNo);<br />
return false;<br />
}<br />
return true;<br />
}<br />
<br />
<br />
<br />
<br />
<br />
<br />
public bool isDebug = false;<br />
private bool executeCommand(string command, out string response) {<br />
byte[] commandBytes = System.Text.Encoding.ASCII.GetBytes((command + CRLF).ToCharArray());<br />
CallTrace("Tx '{0}'", command);<br />
bool isSupressThrow = false;<br />
try {<br />
pop3Stream.Write(commandBytes, 0, commandBytes.Length);<br />
if (isDebug) {<br />
isDebug=false;<br />
throw new IOException("Test", new SocketException(10053));<br />
}<br />
} catch (IOException ex) {<br />
isSupressThrow = executeReconnect(ex, command, commandBytes);<br />
if (!isSupressThrow) {<br />
throw;<br />
}<br />
}<br />
pop3Stream.Flush();<br />
<br />
response = null;<br />
try {<br />
response = pop3StreamReader.ReadLine();<br />
} catch (IOException ex) {<br />
isSupressThrow = executeReconnect(ex, command, commandBytes);<br />
if (isSupressThrow) {<br />
response = pop3StreamReader.ReadLine();<br />
} else {<br />
throw;<br />
}<br />
}<br />
if (response==null) {<br />
throw new Pop3Exception("Server "+ popServer + " has not responded, timeout has occured.");<br />
}<br />
CallTrace("Rx '{0}'", response);<br />
return (response.Length>0 && response[0]=='+');<br />
}<br />
<br />
<br />
private bool executeReconnect(IOException ex, string command, byte[] commandBytes) {<br />
if (ex.InnerException!=null && ex.InnerException is SocketException) {<br />
SocketException innerEx = (SocketException)ex.InnerException;<br />
if (innerEx.ErrorCode==10053) {<br />
CallWarning("ExecuteCommand", "", "probably timeout occured");<br />
if (isAutoReconnect) {<br />
isTimeoutReconnect = true;<br />
try {<br />
CallTrace(" try to auto reconnect");<br />
Connect();<br />
<br />
CallTrace(" reconnect successful, try to resend command");<br />
CallTrace("Tx '{0}'", command);<br />
pop3Stream.Write(commandBytes, 0, commandBytes.Length);<br />
pop3Stream.Flush();<br />
return true;<br />
} finally {<br />
isTimeoutReconnect = false;<br />
}<br />
<br />
}<br />
}<br />
}<br />
return false;<br />
}<br />
<br />
<br />
<br />
<br />
<br />
protected bool readSingleLine(out string response) {<br />
response = null;<br />
try {<br />
response = pop3StreamReader.ReadLine();<br />
} catch (Exception ex) {<br />
string s = ex.Message;<br />
}<br />
if (response==null) {<br />
throw new Pop3Exception("Server "+ popServer + " has not responded, timeout has occured.");<br />
}<br />
CallTrace("Rx '{0}'", response);<br />
return (response.Length>0 && response[0]=='+');<br />
}<br />
<br />
<br />
protected bool readMultiLine(out string response) {<br />
response = null;<br />
response = pop3StreamReader.ReadLine();<br />
if (response==null) {<br />
throw new Pop3Exception("Server "+ popServer + " has not responded, probably timeout has occured.");<br />
}<br />
if (isTraceRawEmail) {<br />
RawEmailSB.Append(response + CRLF);<br />
}<br />
if (response.Length>0 && response[0]=='.') {<br />
if (response==".") {<br />
return false;<br />
}<br />
response = response.Substring(1, response.Length-1);<br />
}<br />
return true;<br />
}<br />
<br />
}<br />
}<br />
}<br />
<br />
"Gödel proved that any formal system that defines the primitive recursive functions must be either incomplete or inconsistent. In particular one could not prove from within the system that the system itself was consistent even though the question could be formulated within the system."
|
|
|
|
|
Please notice my second article http://www.codeproject.com/useritems/Pop3MimeClient.asp[^] There, I analyze the header lines completely according to MIME and one gets highly structured access to them. I have even a list of all UnknowHeaderlines, because the sender of an email is free to invent his own header line types. I hope the new version covers all your needs and anybody else's who needs to do email processing.
|
|
|
|
|
Thanks for a great article and some nice useful code!
Just wondering if anybody knows of a C# class that nicely parses a raw email message (like the ones returned by this program) and gives access to the fields: From, To, Subject, Body, Attachments etc... Obviously I can use Regex, but I thought that maybe this would be a fairly common request and the code might exist out there somewhere?
|
|
|
|
|
Actually, I have completed the code you are asking for. I hope I can write the article and post everything until end of september.
Peter
|
|
|
|
|
|
Thanks, just having a look - seems like more good work!
|
|
|
|
|
Great article.
In the past I have used Indy.Sockets (http://www.indyproject.org/Sockets/index.en.aspx), which does attachments, Pop3 etc...
Might be worth a look.
Nick
|
|
|
|
|
How do i decode UTF7 encoded mails?I have no problems with "quoted-printable" but i can't find a way that works to decode UTF7.
|
|
|
|
|
Hm, it seems quiet a number of people would need my MIMEclient, which is programmed, but not ready yet for CodeProject. Anyway, here is the code how to convert encoded byte arrays to strings:
<br />
public string DecodeByteArryToString(byte[] ByteArray, Encoding ByteEncoding) {<br />
if (ByteArray==null) {<br />
return null;<br />
}<br />
Decoder byteArrayDecoder;<br />
if (ByteEncoding==null){<br />
System.Diagnostics.Debugger.Break();
byteArrayDecoder = Encoding.UTF7.GetDecoder();<br />
}else{<br />
byteArrayDecoder = ByteEncoding.GetDecoder();<br />
}<br />
int charCount = byteArrayDecoder.GetCharCount(ByteArray, 0, ByteArry.Length);<br />
char[] bodyChars = new Char[charCount];<br />
int charsDecodedCount = byteArrayDecoder.GetChars(ByteArray, 0, ByteArray.Length, bodyChars, 0);<br />
return new string(bodyChars);<br />
}<br />
-- modified at 4:26 Thursday 3rd August, 2006
|
|
|
|
|
I tryed it,but it don't works.
Here is how i call it.
<br />
body = DecodeByteArryToString(Encoding.ASCII.GetBytes(body), Encoding.UTF7);<br />
-- modified at 4:43 Thursday 3rd August, 2006
|
|
|
|
|
Your call seems to be correct. But maybe the body is not plain ASCII, but Base64 ? Because I had to code it like this:
<br />
byte[] bodyBytes = System.Convert.FromBase64String(TransferEncodedMessage);<br />
message.Body = DecodeByteArryToString(bodyBytes, message.BodyEncoding);<br />
|
|
|
|
|
I have to say it's a great code you got there. Nicely done.
I have a problem though. After I check for emails once using your code (and it find one message), the second time it finds 0 messages. But the email is still in the Inbox.
Second thing: I would like to be able to download attachments. How can I do that?
Third: Can I also send emails with attachments (using SMTP or something)?
Dan
|
|
|
|
|
1) I don't know why your mail server doesn't list any mails if there is still one left. If you switch on the trace you can check if we send the proper commands and what the server responds. Anyway, you can still try to download the mail, but I guess the server will say there isn't any.
2) Downloading attachments is rather complicated, because the mime standard doesn't specify in details how attachments are done. I'm working on it, but it might take few more weeks.
3) You can send emails with attachments using System.Net.Mail
Cheers, Peter
|
|
|
|
|
Hello Peter.
If there any progress in working with attachment.
waiting for this feature of your application...
|
|
|
|
|
The code is more or less finished to handle MIME attachment, but not properly prepared for Codeproject yet. this might take few more weeks. If i should send you the code as is, then let me know here your email address and I will send it to you.
Peter
|
|
|
|
|
Hi Peter, great work... Any chance of sending the code to handle attachments? I have moved over 400 mail boxes to another system and would like to collect the old emails via POP3 and send them to the new mailboxes. Thanks Chris Foster... chrisfost @ gmail.com
|
|
|
|
|
I don't recommend you to use my program for forwarding emails, because my focus was on POP3 only, i.e. receiving emails. For forwarding, you need to send the emails as well, using SMTP. The SMTP support from .NET is quiet good, but unfortunately is the translation of the email received by POP3 (basically pure ASCII) to Microsoft's SMTP implementation not trivial. Different senders (Microsoft, Yahoo, GMail, Apple, Open Source, you name it) might send attachements, alternate body texts, etc., slightly differently. It would require a great testing effort to ensure that all emails received from different resources are properly translated.
|
|
|
|
|
Hello, please, it also sends me the code with attachments.
wastile@hotmail.com;wagner.amorim@mz-ir.com.
Best Regards,
Wagner Amorim
|
|
|
|
|
Hey peter,
I would also like the attachments code,
Zav@Spiderweb.co.il
Zs
|
|
|
|
|
I would really appreciate the attachment's code too. Please let me know if you can help.
Thanks,
David
|
|
|
|
|
My code for handling MIME and attachments is here on Codeproject:
Pop3 Mime Client
|
|
|
|
|
I appreciate your hard work on this, especially taking the time to go back and add the non-SSL code. Has anyone tried to forward the raw email using System.NET.Mail or would I have to create a new MailMessage and extract the body, subject, etc...?
Thanks again to all who posted.
|
|
|
|
|
I think System.NET.Mail supports only the sending of MailMessages, but my code presently only supplies the raw ASCII code of the email. In a future article I'll show how to convert the various MIME parts into an inherited class of MailMessages. This is rather tricky to accomplish, because the mapping between MIME specifications against attachments and alternate body, as used by MailMessages, is not well defined.
|
|
|
|
|
Hi,
Good solution but not always usable - special solution and not common.
I have tested with my own account ( trough local proxy and K9) and SSL stream is not supported.
Your solution need a fall back when SSL streams are not supported.
elli
|
|
|
|
|
First I want to say its a great article...
_elli_ and others, his solution worked for me, see below how to add non-SSL support.
You need to change the connect, readSingleLine and readMultiLine functions. See the code snippets below to get the idea.
Top of the class:
protected Stream stream;
protected StreamReader reader;
readSingleLine/readMultiLine functions:
try
{
response = reader.ReadLine();
//response = sslStreamReader.ReadLine();
}
connect function:
//I added a SSL boolean property and changed the connect function a little
if (ssl)
{
//get SSL stream
try
{
CallTrace(" Get SSL connection");
sslServerStream = new SslStream(serverTcpConnection.GetStream(), false);
sslServerStream.ReadTimeout = readTimeout;
}
catch (Exception ex)
{
throw new Pop3Exception("Server " + popServer + " found, but cannot get SSL data stream.\nRuntime Error: " + ex.ToString());
}
//perform SSL authentication
try
{
CallTrace(" Get SSL authentication");
sslServerStream.AuthenticateAsClient(popServer);
}
catch (Exception ex)
{
throw new Pop3Exception("Server " + popServer + " found, but problem with SSL Authentication.\nRuntime Error: " + ex.ToString());
}
stream = (Stream)sslServerStream;
}
else
{
stream = serverTcpConnection.GetStream(); // normal tcp stream
}
reader = new StreamReader(stream, Encoding.ASCII);
-- modified at 10:12 Saturday 3rd June, 2006
|
|
|
|
|