public ActionResult Mail() { MimeReader mime = new MimeReader(); var vm = new List <MailViewModel>(); var path = HostingEnvironment.MapPath(@"/App_Data"); foreach (var file in Directory.GetFiles($@"{path}", "*.eml")) { RxMailMessage msg = mime.GetEmail(file); vm.Add(new MailViewModel() { Id = Path.GetFileNameWithoutExtension(file), Sent = msg.DeliveryDate, To = msg.To.Select(s => s.Address.ToString()), CC = msg.CC.Select(s => s.Address.ToString()), From = msg.From.Address, Subject = msg.Subject.Replace("(Trial Version)", ""), Body = msg.Body, Attachments = msg.Attachments.ToList() }); } return(View(vm.OrderByDescending(x => x.Sent))); }
public object Get() { MimeReader mime = new MimeReader(); // this class processes the .EML mime content // this get's the MailMessage into Peter's RxMailMessage class // which is derived from the MS MailMessage class string sEmlPath = @"C:\Temp\emails\approve-task.eml"; RxMailMessage mm = mime.GetEmail(sEmlPath); var dto = _context.Users.Include(g => g.Groups).ToList(); return(Ok(dto)); }
public string GetBody(string path) { MimeReader mime = new MimeReader(); RxMailMessage mm = mime.GetEmail(path); return(GetPlainText(mm)); //divList.Style.Add("display", "none"); //divDetails.Style.Remove("display"); }
private List <stDestinatarios> ObtenerDestinarios(ref RxMailMessage msg, string PST, string Archivo) { List <stDestinatarios> Destinatarios = new List <stDestinatarios> { }; try { if (msg.To.Count > 0) { foreach (System.Net.Mail.MailAddress address in msg.To) { stDestinatarios dest = new stDestinatarios(address.Address, address.DisplayName); Destinatarios.Add(dest); } } if (msg.CC.Count > 0) { foreach (System.Net.Mail.MailAddress address in msg.CC) { stDestinatarios dest = new stDestinatarios(address.Address, address.DisplayName); Destinatarios.Add(dest); } } if (msg.Bcc.Count > 0) { foreach (System.Net.Mail.MailAddress address in msg.Bcc) { stDestinatarios dest = new stDestinatarios(address.Address, address.DisplayName); Destinatarios.Add(dest); } } } catch (Exception ex) { RegistrarLogLocal("ObtenerDestinarios", ex.Message, PST, Archivo); } return(Destinatarios); }
private string GetMailText(RxMailMessage mm) { // check for plain text in body if (!mm.IsBodyHtml && !string.IsNullOrEmpty(mm.Body)) { return(mm.Body); } string sText = string.Empty; foreach (System.Net.Mail.AlternateView av in mm.AlternateViews) { // check for plain text if (string.Compare(av.ContentType.MediaType, "text/plain", true) == 0) { continue;// return StreamToString(av.ContentStream); } // check for HTML text if (string.Compare(av.ContentType.MediaType, "text/html", true) == 0) { sText = StreamToString(av.ContentStream); } } // HTML is our only hope if (sText == string.Empty && mm.IsBodyHtml && !string.IsNullOrEmpty(mm.Body)) { sText = mm.Body; } if (sText == string.Empty) { return(string.Empty); } else { return(sText); } // need to convert the HTML to plaintext //return PgUtil.StripHTML(sText); }
private static void readMail() { try { foreach (string file in Directory.EnumerateFiles(ConfigurationManager.AppSettings["sEmlPath"])) { if (file.Contains(".msg")) { ReadMsgFile.ReadOutlookMail(file); } else { MimeReader mime = new MimeReader(); RxMailMessage mm = mime.GetEmail(file); string detils = ReadEmlFile.GetPlainText(mm); } } } catch (Exception) { throw; } }
/// <summary> /// Add all attachments and alternative views from child to the parent /// </summary> private void AddChildPartsToParent(RxMailMessage child, RxMailMessage parent) { //add the child itself to the parent parent.Entities.Add(child); //add the alternative views of the child to the parent if (child.AlternateViews != null) { foreach (AlternateView childView in child.AlternateViews) { parent.AlternateViews.Add(childView); } } //add the body of the child as alternative view to parent //this should be the last view attached here, because the POP 3 MIME client //is supposed to display the last alternative view if (child.MediaMainType == "text" && child.ContentStream != null&& child.Parent.ContentType != null&& child.Parent.ContentType.MediaType.ToLowerInvariant() == "multipart/alternative") { AlternateView thisAlternateView = new AlternateView(child.ContentStream); thisAlternateView.ContentId = RemoveBrackets(child.ContentId); thisAlternateView.ContentType = child.ContentType; thisAlternateView.TransferEncoding = child.ContentTransferEncoding; parent.AlternateViews.Add(thisAlternateView); } //add the attachments of the child to the parent if (child.Attachments != null) { foreach (Attachment childAttachment in child.Attachments) { parent.Attachments.Add(childAttachment); } } }
/// <summary> /// each attachement is stored in its own MIME entity and read into this entity's /// ContentStream. SaveAttachment creates an attachment out of the ContentStream /// and attaches it to the parent MIME entity. /// </summary> private void SaveAttachment(RxMailMessage message) { if (message.Parent == null) { System.Diagnostics.Debugger.Break(); //didn't have a sample email to test this } else { Attachment thisAttachment = new Attachment(message.ContentStream, message.ContentType); //no idea why ContentDisposition is read only. on the other hand, it is anyway redundant if (message.ContentDisposition != null) { ContentDisposition messageContentDisposition = message.ContentDisposition; ContentDisposition AttachmentContentDisposition = thisAttachment.ContentDisposition; if (messageContentDisposition.CreationDate > DateTime.MinValue) { AttachmentContentDisposition.CreationDate = messageContentDisposition.CreationDate; } AttachmentContentDisposition.DispositionType = messageContentDisposition.DispositionType; AttachmentContentDisposition.FileName = messageContentDisposition.FileName; AttachmentContentDisposition.Inline = messageContentDisposition.Inline; if (messageContentDisposition.ModificationDate > DateTime.MinValue) { AttachmentContentDisposition.ModificationDate = messageContentDisposition.ModificationDate; } // see note below //AttachmentContentDisposition.Parameters.Clear(); if (messageContentDisposition.ReadDate > DateTime.MinValue) { AttachmentContentDisposition.ReadDate = messageContentDisposition.ReadDate; } if (messageContentDisposition.Size > 0) { AttachmentContentDisposition.Size = messageContentDisposition.Size; } // I think this is a bug. Setting the ContentDisposition values above had // already set the Parameters collection so I got an error when the attempt // was made to add the same parameter again //foreach (string key in messageContentDisposition.Parameters.Keys) //{ // AttachmentContentDisposition.Parameters.Add(key, messageContentDisposition.Parameters[key]); //} } //get ContentId string contentIdString = message.ContentId; if (contentIdString != null) { thisAttachment.ContentId = RemoveBrackets(contentIdString); } thisAttachment.TransferEncoding = message.ContentTransferEncoding; message.Parent.Attachments.Add(thisAttachment); } }
private void decodeEntity(RxMailMessage entity) { AppendLine("From : {0}", entity.From); AppendLine("Sender: {0}", entity.Sender); AppendLine("To : {0}", entity.To); AppendLine("CC : {0}", entity.CC); AppendLine("ReplyT: {0}", entity.ReplyTo); AppendLine("Sub : {0}", entity.Subject); AppendLine("S-Enco: {0}", entity.SubjectEncoding); if (entity.DeliveryDate > DateTime.MinValue) { AppendLine("Date : {0}", entity.DeliveryDate); } if (entity.Priority != MailPriority.Normal) { AppendLine("Priori: {0}", entity.Priority); } if (entity.Body.Length > 0) { AppendLine("Body : {0} byte(s)", entity.Body.Length); AppendLine("B-Enco: {0}", entity.BodyEncoding); } else { if (entity.BodyEncoding != Encoding.ASCII) { AppendLine("B-Enco: {0}", entity.BodyEncoding); } } AppendLine("T-Type: {0}", entity.TransferType); AppendLine("C-Type: {0}", entity.ContentType); AppendLine("C-Desc: {0}", entity.ContentDescription); AppendLine("C-Disp: {0}", entity.ContentDisposition); AppendLine("C-Id : {0}", entity.ContentId); AppendLine("M-ID : {0}", entity.MessageId); AppendLine("Mime : Version {0}", entity.MimeVersion); if (entity.ContentStream != null) { AppendLine("Stream: Length {0}", entity.ContentStream.Length); } //decode all shild MIME entities foreach (RxMailMessage child in entity.Entities) { m_mailStructure.AppendLine("------------------------------------"); decodeEntity(child); } if (entity.ContentType != null&& entity.ContentType.MediaType != null&& entity.ContentType.MediaType.StartsWith("multipart")) { AppendLine("End {0}", entity.ContentType.ToString()); } }
// Constructors // ------------ /// <summary> /// default constructor /// </summary> public RxMailMessage() { //for the moment, we assume to be at the top //should this entity become a child, TopParent will be overwritten TopParent = this; Entities = new List<RxMailMessage>(); UnknowHeaderlines = new List<string>(); }
/// <summary> /// Convert one MIME header field and update message accordingly /// </summary> private void ProcessHeaderField(RxMailMessage message, string headerField) { string headerLineType; string headerLineContent; int separatorPosition = headerField.IndexOf(':'); if (separatorPosition < 1) { // header field type not found, skip this line callGetEmailWarning("character \':\' missing in header format field: \'{0}\'", headerField); } else { //process header field type headerLineType = headerField.Substring(0, separatorPosition).ToLowerInvariant(); headerLineContent = headerField.Substring(separatorPosition + 1).Trim(WhiteSpaceChars); if (headerLineType == "" || headerLineContent == "") { //1 of the 2 parts missing, drop the line return; } // add header line to headers message.Headers.Add(headerLineType, headerLineContent); //interpret if possible switch (headerLineType) { case "bcc": AddMailAddresses(headerLineContent, message.Bcc); break; case "cc": AddMailAddresses(headerLineContent, message.CC); break; case "content-description": message.ContentDescription = headerLineContent; break; case "content-disposition": message.ContentDisposition = new ContentDisposition(headerLineContent); break; case "content-id": message.ContentId = headerLineContent; break; case "content-transfer-encoding": message.TransferType = headerLineContent; message.ContentTransferEncoding = ConvertToTransferEncoding(headerLineContent); break; case "content-type": message.SetContentTypeFields(headerLineContent); break; case "date": message.DeliveryDate = ConvertToDateTime(headerLineContent); break; case "delivered-to": message.DeliveredTo = ConvertToMailAddress(headerLineContent); break; case "from": MailAddress address = ConvertToMailAddress(headerLineContent); if (address != null) { message.From = address; } break; case "message-id": message.MessageId = headerLineContent; break; case "mime-version": message.MimeVersion = headerLineContent; break; //message.BodyEncoding = new Encoding(); case "sender": message.Sender = ConvertToMailAddress(headerLineContent); break; case "subject": message.Subject = headerLineContent; break; case "received": break; //throw mail routing information away case "reply-to": message.ReplyTo = ConvertToMailAddress(headerLineContent); break; case "return-path": message.ReturnPath = ConvertToMailAddress(headerLineContent); break; case "to": AddMailAddresses(headerLineContent, message.To); break; default: message.UnknowHeaderlines.Add(headerField); if (isCollectUnknowHeaderLines) { AllUnknowHeaderLines.Add(headerField); } break; } } }
/// <summary> /// Process a MIME entity /// /// A MIME entity consists of header and body. /// Separator lines in the body might mark children MIME entities /// </summary> private MimeEntityReturnCode ProcessMimeEntity(RxMailMessage message, string parentBoundaryStart) { bool hasParentBoundary = parentBoundaryStart.Length > 0; string parentBoundaryEnd = parentBoundaryStart + "--"; MimeEntityReturnCode boundaryMimeReturnCode = new MimeEntityReturnCode(); //some format fields are inherited from parent, only the default for //ContentType needs to be set here, otherwise the boundary parameter would be //inherited too ! message.SetContentTypeFields("text/plain; charset=us-ascii"); //get header //---------- string completeHeaderField = null; //consists of one start line and possibly several continuation lines string response = string.Empty; // read header lines until empty line is found (end of header) while (true) { if (! readMultiLine(ref response)) { //POP3 server has not send any more lines callGetEmailWarning("incomplete MIME entity header received", null); //empty this message while (readMultiLine(ref response)) { } System.Diagnostics.Debugger.Break(); //didn't have a sample email to test this return MimeEntityReturnCode.problem; } if (response.Length < 1) { //empty line found => end of header if (completeHeaderField != null) { ProcessHeaderField(message, completeHeaderField); } else { //there was only an empty header. } break; } //check if there is a parent boundary in the header (wrong format!) if (hasParentBoundary && parentBoundaryFound(response, parentBoundaryStart, parentBoundaryEnd, ref boundaryMimeReturnCode)) { callGetEmailWarning("MIME entity header prematurely ended by parent boundary", null); //empty this message while (readMultiLine(ref response)) { } System.Diagnostics.Debugger.Break(); //didn't have a sample email to test this return boundaryMimeReturnCode; } //read header field //one header field can extend over one start line and multiple continuation lines //a continuation line starts with at least 1 blank (' ') or tab if (response[0] == ' ' || response[0] == '\t') { //continuation line found. if (completeHeaderField == null) { callGetEmailWarning("Email header starts with continuation line", null); //empty this message while (readMultiLine(ref response)) { } System.Diagnostics.Debugger.Break(); //didn't have a sample email to test this return MimeEntityReturnCode.problem; } else { // append space, if needed, and continuation line if (completeHeaderField[completeHeaderField.Length - 1] != ' ') { //previous line did not end with a whitespace //need to replace CRLF with a ' ' completeHeaderField += ' ' + response.TrimStart(WhiteSpaceChars); } else { //previous line did end with a whitespace completeHeaderField += response.TrimStart(WhiteSpaceChars); } } } else { //a new header field line found if (completeHeaderField == null) { //very first field, just copy it and then check for continuation lines completeHeaderField = response; } else { //new header line found ProcessHeaderField(message, completeHeaderField); //save the beginning of the next line completeHeaderField = response; } } } //end while read header lines //process body //------------ MimeEntitySB.Length = 0; //empty StringBuilder. For speed reasons, reuse StringBuilder defined as member of class string BoundaryDelimiterLineStart = null; bool isBoundaryDefined = false; if (message.ContentType.Boundary != null) { isBoundaryDefined = true; BoundaryDelimiterLineStart = "--" + message.ContentType.Boundary; } //prepare return code for the case there is no boundary in the body boundaryMimeReturnCode = MimeEntityReturnCode.bodyComplete; //read body lines while (readMultiLine(ref response)) { //check if there is a boundary line from this entity itself in the body if (isBoundaryDefined && response.TrimEnd(null) == BoundaryDelimiterLineStart) { //boundary line found. //stop the processing here and start a delimited body processing return ProcessDelimitedBody(message, BoundaryDelimiterLineStart, parentBoundaryStart, parentBoundaryEnd); } //check if there is a parent boundary in the body if (hasParentBoundary && parentBoundaryFound(response, parentBoundaryStart, parentBoundaryEnd, ref boundaryMimeReturnCode)) { //a parent boundary is found. Decode the content of the body received so far, then end this MIME entity //note that boundaryMimeReturnCode is set here, but used in the return statement break; } //process next line MimeEntitySB.Append(response + CRLF); } //a complete MIME body read //convert received US ASCII characters to .NET string (Unicode) string TransferEncodedMessage = MimeEntitySB.ToString(); bool isAttachmentSaved = false; switch (message.ContentTransferEncoding) { case TransferEncoding.SevenBit: //nothing to do saveMessageBody(message, TransferEncodedMessage); break; case TransferEncoding.Base64: //convert base 64 -> byte[] byte[] bodyBytes = System.Convert.FromBase64String(TransferEncodedMessage); message.ContentStream = new MemoryStream(bodyBytes, false); if (message.MediaMainType == "text") { //convert byte[] -> string message.Body = DecodeByteArryToString(bodyBytes, message.BodyEncoding); } else if (message.MediaMainType == "image" || message.MediaMainType == "application") { SaveAttachment(message); isAttachmentSaved = true; } break; case TransferEncoding.QuotedPrintable: saveMessageBody(message, QuotedPrintable.Decode(TransferEncodedMessage)); break; default: saveMessageBody(message, TransferEncodedMessage); break; //no need to raise a warning here, the warning was done when analising the header } if (message.ContentDisposition != null&& message.ContentDisposition.DispositionType.ToLowerInvariant() == "attachment" && (! isAttachmentSaved)) { SaveAttachment(message); isAttachmentSaved = true; } return boundaryMimeReturnCode; }
/// <summary> /// Gets 1 email from POP3 server and processes it. /// </summary> /// <param name="MessageNo">Email Id to be fetched from POP3 server</param> /// <param name="Message">decoded email</param> /// <returns>false: no email received or email not properly formatted</returns> public bool GetEmail(int MessageNo, ref RxMailMessage Message) { Message = null; //request email, send RETRieve command to POP3 server if (! SendRetrCommand(MessageNo)) { return false; } //prepare message, set defaults as specified in RFC 2046 //although they get normally overwritten, we have to make sure there are at least defaults Message = new RxMailMessage(); Message.ContentTransferEncoding = TransferEncoding.SevenBit; Message.TransferType = "7bit"; this.m_messageNo = MessageNo; //raw email tracing if (isGetRawEmail) { isTraceRawEmail = true; if (RawEmailSB == null) { RawEmailSB = new StringBuilder(100000); } else { RawEmailSB.Length = 0; } } //convert received email into RxMailMessage MimeEntityReturnCode MessageMimeReturnCode = ProcessMimeEntity(Message, ""); if (isGetRawEmail) { //add raw email version to message Message.RawContent = RawEmailSB.ToString(); isTraceRawEmail = false; } if (MessageMimeReturnCode == MimeEntityReturnCode.bodyComplete || MessageMimeReturnCode == MimeEntityReturnCode.parentBoundaryEndFound) { TraceFrom("email with {0} body chars received", Message.Body.Length); return true; } return false; }
private MimeEntityReturnCode ProcessDelimitedBody( RxMailMessage message, string BoundaryStart, string parentBoundaryStart, string parentBoundaryEnd) { string response; if (BoundaryStart.Trim()==parentBoundaryStart.Trim()) { //Mime entity boundaries have to be unique callGetEmailWarning("new boundary same as parent boundary: '{0}'", parentBoundaryStart); //empty this message while (readMultiLine(out response)) { } return MimeEntityReturnCode.problem; } // MimeEntityReturnCode ReturnCode; do { //empty StringBuilder MimeEntitySB.Length = 0; RxMailMessage ChildPart = message.CreateChildEntity(); //recursively call MIME part processing ReturnCode = ProcessMimeEntity(ChildPart, BoundaryStart); if (ReturnCode == MimeEntityReturnCode.problem) { //it seems the received email doesn't follow the MIME specification. Stop here return MimeEntityReturnCode.problem; } //***************************************************************************************************************** // Added the below to ensure that the message body is always set when working with MIME MULTIPART content // NOTE: // Outlook 2007 sends two parts when sending an email as HTML (I think this is the same for other email clients): // 1. The first part seems to be PLAIN TEXT // 2. The second part seems to be HTML TEXT // Since this is a MULTIPART we want to set this body to the second HTML PART // If other clients only send one part for HTML then this method will not be called // If you want to set the Body to the TEXT only PART then you need to change the MimeEntityReturnCode.parentBoundaryEndFound flag to MimeEntityReturnCode.parentBoundaryStartFound //***************************************************************************************************************** if (ReturnCode == MimeEntityReturnCode.parentBoundaryEndFound && (message.Body == null || message.Body == String.Empty) && ChildPart.Body != null && ChildPart.Body != String.Empty) { message.Body = ChildPart.Body.Trim(); } //add the newly found child MIME part to the parent AddChildPartsToParent(ChildPart, message); } while (ReturnCode != MimeEntityReturnCode.parentBoundaryEndFound); //disregard all future lines until parent boundary is found or end of complete message MimeEntityReturnCode boundaryMimeReturnCode; bool hasParentBoundary = parentBoundaryStart.Length>0; while (readMultiLine(out response)) { if (hasParentBoundary && parentBoundaryFound(response, parentBoundaryStart, parentBoundaryEnd, out boundaryMimeReturnCode)) { return boundaryMimeReturnCode; } } return MimeEntityReturnCode.bodyComplete; }
/// <summary> /// Copies the content found for the MIME entity to the RxMailMessage body and creates /// a stream which can be used to create attachements, alternative views, ... /// </summary> private void saveMessageBody(RxMailMessage message, string contentString) { message.Body = contentString; System.Text.Encoding ascii = System.Text.Encoding.ASCII; MemoryStream bodyStream = new MemoryStream(ascii.GetBytes(contentString), 0, contentString.Length); message.ContentStream = bodyStream; }
private void LeerEML(string Carpeta, string Archivo, string PST, Int16 IdPST) { try { MimeReader mime = new MimeReader(); string Remitente = ""; Int64 IdCorreo = 0; //FechaIniPerf = DateTime.Now; //TrackPerformance RxMailMessage msg = mime.GetEmail(Archivo); //RegistrarLogDesempenno("GetEmail"); //TrackPerformance if (msg != null) { List <stAdjuntos> Adjuntos = new List <stAdjuntos> { }; List <stDestinatarios> Destinatarios = new List <stDestinatarios> { }; //FechaIniPerf = DateTime.Now; //TrackPerformance Adjuntos = ObtenerAdjuntos(Carpeta, Archivo, PST); //RegistrarLogDesempenno("ObtenerAdjuntos"); //TrackPerformance //FechaIniPerf = DateTime.Now; //TrackPerformance Destinatarios = ObtenerDestinarios(ref msg, PST, Archivo); //RegistrarLogDesempenno("ObtenerDestinarios"); //TrackPerformance if (msg.From != null) { Remitente = msg.From.Address; } else { if (msg.Sender != null) { Remitente = msg.Sender.Address; } else { Remitente = ""; } } //FechaIniPerf = DateTime.Now; //TrackPerformance IdCorreo = InsertarCorreo(IdPST, Remitente, msg.DeliveryDate, msg.Subject, GetMailText(msg), Archivo, PST, Carpeta.Replace(vRuta, "")); //RegistrarLogDesempenno("InsertarCorreo"); //TrackPerformance if (IdCorreo > 0) { foreach (stAdjuntos att in Adjuntos.Distinct()) { try { //FechaIniPerf = DateTime.Now; //TrackPerformance InsertarAdjuntos(IdCorreo, Carpeta.Replace(vRuta, ""), att.Archivo, att.Extension, att.Tamanno); //RegistrarLogDesempenno("InsertarAdjuntos"); //TrackPerformance } catch (Exception ex) { RegistrarLogLocal("InsertarAdjuntosCall", ex.Message, PST, Archivo); } } List <string> DestinatariosF = new List <string> { }; foreach (stDestinatarios dest in Destinatarios.Distinct()) { try { //FechaIniPerf = DateTime.Now; //TrackPerformance if (!DestinatariosF.Contains(dest.Direccion)) { InsertarDestinatarios(IdCorreo, dest.Direccion, dest.Nombre); DestinatariosF.Add(dest.Direccion); } //RegistrarLogDesempenno("InsertarDestinatarios"); //TrackPerformance } catch (Exception ex) { RegistrarLogLocal("InsertarDestinatariosCall", ex.Message, PST, Archivo); } } } msg.Dispose(); } } catch (Exception ex) { RegistrarLogLocal("LeerEML", ex.Message, PST, Archivo); } }
/// <summary> /// Copies the content found for the MIME entity to the RxMailMessage body and creates /// a stream which can be used to create attachements, alternative views, ... /// </summary> private void saveMessageBody(RxMailMessage message, string contentString) { message.Body = contentString; MemoryStream bodyStream = new MemoryStream(); StreamWriter bodyStreamWriter = new StreamWriter(bodyStream); bodyStreamWriter.Write(contentString); int l = contentString.Length; bodyStreamWriter.Flush(); message.ContentStream = bodyStream; }
/// <summary> /// Creates an empty child MIME entity from the parent MIME entity. /// /// An email can consist of several MIME entities. A entity has the same structure /// like an email, that is header and body. The child inherits few properties /// from the parent as default value. /// </summary> public RxMailMessage CreateChildEntity() { RxMailMessage child = new RxMailMessage(); child.Parent = this; child.TopParent = this.TopParent; child.ContentTransferEncoding = this.ContentTransferEncoding; return child; }
/// <summary> /// each attachement is stored in its own MIME entity and read into this entity's /// ContentStream. SaveAttachment creates an attachment out of the ContentStream /// and attaches it to the parent MIME entity. /// </summary> private void SaveAttachment(RxMailMessage message) { if (message.Parent == null) { System.Diagnostics.Debugger.Break(); //didn't have a sample email to test this } else { Attachment thisAttachment = new Attachment(message.ContentStream, message.ContentType); //no idea why ContentDisposition is read only. on the other hand, it is anyway redundant if (message.ContentDisposition != null) { ContentDisposition messageContentDisposition = message.ContentDisposition; ContentDisposition AttachmentContentDisposition = thisAttachment.ContentDisposition; if (messageContentDisposition.CreationDate > DateTime.MinValue) { AttachmentContentDisposition.CreationDate = messageContentDisposition.CreationDate; } AttachmentContentDisposition.DispositionType = messageContentDisposition.DispositionType; AttachmentContentDisposition.FileName = messageContentDisposition.FileName; AttachmentContentDisposition.Inline = messageContentDisposition.Inline; if (messageContentDisposition.ModificationDate > DateTime.MinValue) { AttachmentContentDisposition.ModificationDate = messageContentDisposition.ModificationDate; } AttachmentContentDisposition.Parameters.Clear(); if (messageContentDisposition.ReadDate > DateTime.MinValue) { AttachmentContentDisposition.ReadDate = messageContentDisposition.ReadDate; } if (messageContentDisposition.Size > 0) { AttachmentContentDisposition.Size = messageContentDisposition.Size; } foreach (string key in messageContentDisposition.Parameters.Keys) { AttachmentContentDisposition.Parameters.Add(key, messageContentDisposition.Parameters[key]); } } //get ContentId string contentIdString = message.ContentId; if (contentIdString != null) { thisAttachment.ContentId = RemoveBrackets(contentIdString); } thisAttachment.TransferEncoding = message.ContentTransferEncoding; message.Parent.Attachments.Add(thisAttachment); } }
private MimeEntityReturnCode ProcessDelimitedBody(RxMailMessage message, string BoundaryStart, string parentBoundaryStart, string parentBoundaryEnd) { string response = string.Empty; if (BoundaryStart.Trim() == parentBoundaryStart.Trim()) { //Mime entity boundaries have to be unique callGetEmailWarning("new boundary same as parent boundary: \'{0}\'", parentBoundaryStart); //empty this message while (readMultiLine(ref response)) { } return MimeEntityReturnCode.problem; } // MimeEntityReturnCode ReturnCode = new MimeEntityReturnCode(); do { //empty StringBuilder MimeEntitySB.Length = 0; RxMailMessage ChildPart = message.CreateChildEntity(); //recursively call MIME part processing ReturnCode = ProcessMimeEntity(ChildPart, BoundaryStart); if (ReturnCode == MimeEntityReturnCode.problem) { //it seems the received email doesn't follow the MIME specification. Stop here return MimeEntityReturnCode.problem; } //add the newly found child MIME part to the parent AddChildPartsToParent(ChildPart, message); } while (ReturnCode != MimeEntityReturnCode.parentBoundaryEndFound); //disregard all future lines until parent boundary is found or end of complete message MimeEntityReturnCode boundaryMimeReturnCode = new MimeEntityReturnCode(); bool hasParentBoundary = parentBoundaryStart.Length > 0; while (readMultiLine(ref response)) { if (hasParentBoundary && parentBoundaryFound(response, parentBoundaryStart, parentBoundaryEnd, ref boundaryMimeReturnCode)) { return boundaryMimeReturnCode; } } return MimeEntityReturnCode.bodyComplete; }
/// <summary> /// Gets an email from the supplied Email Stream and processes it. /// </summary> /// <param name="sEmlPath">Stream that designates the an Email stream</param> /// <returns>RxMailMessage or null if email not properly formatted</returns> public RxMailMessage GetEmail(Stream EmailStream) { EmailStreamReader = new StreamReader(EmailStream, Encoding.ASCII); //prepare message, set defaults as specified in RFC 2046 //although they get normally overwritten, we have to make sure there are at least defaults RxMailMessage Message = new RxMailMessage(); Message.ContentTransferEncoding = TransferEncoding.SevenBit; Message.TransferType = "7bit"; //convert received email into RxMailMessage MimeEntityReturnCode MessageMimeReturnCode = ProcessMimeEntity(Message, ""); if (MessageMimeReturnCode == MimeEntityReturnCode.bodyComplete || MessageMimeReturnCode == MimeEntityReturnCode.parentBoundaryEndFound) { // I've seen EML files that don't have a "To: entity but have "x-receiver:" entity set to the recipient. check and use that if need be if (Message.To.Count == 0) { // do something with string sTo = Message.Headers["x-receiver"]; if (!string.IsNullOrEmpty(sTo)) Message.To.Add(sTo); } // From: maybe also but never have seen it missing if (Message.From == null) { // do something with string sFrom = Message.Headers["x-sender"]; if (!string.IsNullOrEmpty(sFrom)) Message.From = new MailAddress(sFrom); } //TraceFrom("email with {0} body chars received", Message.Body.Length); return Message; } return null; }