///<summary>Converts the Health.Direct.Common.Mail.Message into an OD EmailMessage.  The Direct library is used for both encrypted and unencrypted email.  Set hasAttachments to false to exclude attachments.</summary>
		private static EmailMessage ConvertMessageToEmailMessage(Health.Direct.Common.Mail.Message message,bool hasAttachments) {
			//No need to check RemotingRole; no call to db.
			EmailMessage emailMessage=new EmailMessage();
			emailMessage.FromAddress=message.FromValue.Trim();
			if(message.DateValue!=null) {//Is null when sending, but should not be null when receiving.
				//The received email message date must be in a very specific format and must match the RFC822 standard.  Is a required field for RFC822.  http://tools.ietf.org/html/rfc822
				//We need the received time from the server, so we can quickly identify messages which have already been downloaded and to avoid downloading duplicates.
				//Examples: "3 Dec 2013 17:10:37 -0800", "10 Dec 2013 17:10:37 -0800", "Tue, 5 Nov 2013 17:10:37 +0000 (UTC)", "Tue, 12 Nov 2013 17:10:37 +0000 (UTC)"
				if(message.DateValue.Contains(",")) {//The day-of-week, comma and following space are optional. Examples: "Tue, 3 Dec 2013 17:10:37 +0000", "Tue, 12 Nov 2013 17:10:37 +0000 (UTC)"
					try {
						emailMessage.MsgDateTime=DateTime.ParseExact(message.DateValue.Substring(0,31),"ddd, d MMM yyyy HH:mm:ss zzz",System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat);
					}
					catch {
						emailMessage.MsgDateTime=DateTime.ParseExact(message.DateValue.Substring(0,30),"ddd, d MMM yyyy HH:mm:ss zzz",System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat);
					}
				}
				else {//Examples: "3 Dec 2013 17:10:37 -0800", "12 Nov 2013 17:10:37 -0800 (UTC)"
					try {
						emailMessage.MsgDateTime=DateTime.ParseExact(message.DateValue.Substring(0,26),"d MMM yyyy HH:mm:ss zzz",System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat);
					}
					catch {
						emailMessage.MsgDateTime=DateTime.ParseExact(message.DateValue.Substring(0,25),"d MMM yyyy HH:mm:ss zzz",System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat);
					}
				}
			}
			else {//Sending the email.
				emailMessage.MsgDateTime=DateTime.Now;
			}
			emailMessage.Subject=Tidy(message.SubjectValue);
			emailMessage.ToAddress=message.ToValue.Trim();
			List<Health.Direct.Common.Mime.MimeEntity> listMimeParts=new List<Health.Direct.Common.Mime.MimeEntity>();//We want to treat one part and multiple part emails the same way below, so we make our own list.  If GetParts() is called when IsMultiPart is false, then an exception will be thrown by the Direct library.
			Health.Direct.Common.Mime.MimeEntity mimeEntity=null;
			try {
				mimeEntity=message.ExtractMimeEntity();
			}
			catch {
				emailMessage.BodyText=ProcessMimeTextPart(message.Body.Text);
				return emailMessage;
			}
			if(message.IsMultiPart) {
				foreach(Health.Direct.Common.Mime.MimeEntity mimePart in mimeEntity.GetParts()) {
					listMimeParts.Add(mimePart);
				}
			}
			else {//Single body part.
				listMimeParts.Add(mimeEntity);
			}
			List<Health.Direct.Common.Mime.MimeEntity> listMimeBodyTextParts=new List<Health.Direct.Common.Mime.MimeEntity>();
			List<Health.Direct.Common.Mime.MimeEntity> listMimeAttachParts=new List<Health.Direct.Common.Mime.MimeEntity>();
			for(int i=0;i<listMimeParts.Count;i++) {
				Health.Direct.Common.Mime.MimeEntity mimePart=listMimeParts[i];
				if(mimePart.ContentDisposition==null || !mimePart.ContentDisposition.ToLower().Contains("attachment")) {//Not an email attachment.  Treat as body text.
					listMimeBodyTextParts.Add(mimePart);
				}
				else {
					listMimeAttachParts.Add(mimePart);
				}
			}
			string strTextPartBoundary="";
			if(listMimeBodyTextParts.Count>1) {
				strTextPartBoundary=message.ParsedContentType.Boundary;
			}
			StringBuilder sbBodyText=new StringBuilder();
			for(int i=0;i<listMimeBodyTextParts.Count;i++) {
				if(strTextPartBoundary!="") {//For incoming Direct Ack messages.
					sbBodyText.Append("\r\n--"+strTextPartBoundary+"\r\n");
					sbBodyText.Append(listMimeBodyTextParts[i].ToString());//Includes not only the body text, but also content type and content disposition.
				}
				else {
					sbBodyText.Append(ProcessMimeTextPart(listMimeBodyTextParts[i].Body.Text));
				}
			}
			if(strTextPartBoundary!="") {
				sbBodyText.Append("\r\n--"+strTextPartBoundary+"--\r\n");
			}
			emailMessage.BodyText=sbBodyText.ToString();
			emailMessage.Attachments=new List<EmailAttach>();
			if(!hasAttachments) {
				return emailMessage;
			}
			for(int i=0;i<listMimeAttachParts.Count;i++) {
				Health.Direct.Common.Mime.MimeEntity mimePartAttach=listMimeAttachParts[i];
				string strAttachText=mimePartAttach.Body.Text;
				try {
					if(mimePartAttach.ContentTransferEncoding.ToLower().Contains("base64")) {
						strAttachText=Encoding.UTF8.GetString(Convert.FromBase64String(mimePartAttach.Body.Text));
					}
				}
				catch {
				}
				EmailAttach emailAttach=CreateAttachInAttachPath(mimePartAttach.ParsedContentType.Name,strAttachText);
				if(mimePartAttach.ParsedContentType.Name.ToLower()=="smime.p7m") {//encrypted attachment
					message.ContentType="application/pkcs7-mime; name=smime.p7m; boundary="+strTextPartBoundary+";";
				}
				emailMessage.Attachments.Add(emailAttach);//The attachment EmailMessageNum is set when the emailMessage is inserted/updated below.					
			}
			return emailMessage;
		}
Beispiel #2
0
		///<summary>Gets all mime parts in the message which do not have child mime parts.  Returns null on error.</summary>
		private static List<Health.Direct.Common.Mime.MimeEntity> GetMimeLeafNodes(Health.Direct.Common.Mail.Message message) {
			//No need to check RemotingRole; no call to db.
			//Think of the mime structure as a tree.
			List<Health.Direct.Common.Mime.MimeEntity> listMimePartLeafNodes=new List<Health.Direct.Common.Mime.MimeEntity>();
			Health.Direct.Common.Mime.MimeEntity mimeEntity=null;
			try {
				mimeEntity=message.ExtractMimeEntity();
			}
			catch {
				return null;			
			}
			//If GetParts() is called when IsMultiPart is false, then an exception will be thrown by the Direct library.
			if(message.IsMultiPart) {
				List<Health.Direct.Common.Mime.MimeEntity> listMimeMultiPart=new List<Health.Direct.Common.Mime.MimeEntity>();
				listMimeMultiPart.Add(mimeEntity);
				while(listMimeMultiPart.Count>0) {
					foreach(Health.Direct.Common.Mime.MimeEntity mimePart in listMimeMultiPart[0].GetParts()) {
						if(mimePart.IsMultiPart) {
							listMimeMultiPart.Add(mimePart);
						}
						else {
							listMimePartLeafNodes.Add(mimePart);
						}
					}
					listMimeMultiPart.RemoveAt(0);
				}
			}
			else {//Single body part.
				listMimePartLeafNodes.Add(mimeEntity);
			}
			return listMimePartLeafNodes;
		}