/// <summary> /// Parses the MIME part. /// </summary> /// <param name="data">The data.</param> /// <returns></returns> public static MimePart ParseMimePart(string data, Message message) { MimePart part = new MimePart(); part.ParentMessage = message; part.OriginalContent = data; try { // Separate header and body. int headerEnd = Regex.Match(data, @".(?=\r?\n\r?\n)").Index + 1; int bodyStart = Regex.Match(data, @"(?<=\r?\n\r?\n).").Index; //TODO: remove this workaround if (bodyStart == 0) { //bodyStart = data.IndexOf("\r\n\r\n"); // Fix for a bug - the bodyStart was -1 (Invalid), MCALADO: 04/07/2008 int indexBody = data.IndexOf("\r\n\r\n"); if (indexBody > 0) { bodyStart = indexBody; } } if (data.Length >= headerEnd) { string header = data.Substring(0, headerEnd); header = Parser.Unfold(header); //header = header); // The bodyStart need to be greather than data.length - MCALADO: 04/07/2008 string body = string.Empty; if (bodyStart < data.Length) { body = data.Substring(bodyStart); } // Store the (maybe still encoded) body. part.TextContent = body; // Parse header fields and their parameters. Match m = Regex.Match(header, @"(?<=((\r?\n)|\n)|\A)\S+:(.|(\r?\n[\t ]))+(?=((\r?\n)\S)|\Z)"); while (m.Success) { if (m.Value.ToLower().StartsWith("content-type:")) { part.ContentType = Parser.GetContentType(m.Value); } else if (m.Value.ToLower().StartsWith("content-disposition:")) { part.ContentDisposition = Parser.GetContentDisposition(m.Value); } part.HeaderFields.Add(FormatFieldName(m.Value.Substring(0, m.Value.IndexOf(':'))), Codec.RFC2047Decode(m.Value.Substring(m.Value.IndexOf(':') + 1).Trim(' ', '\r', '\n'))); part.HeaderFieldNames.Add(FormatFieldName(m.Value.Substring(0, m.Value.IndexOf(':'))), Codec.RFC2047Decode(m.Value.Substring(0, m.Value.IndexOf(':')).Trim(' ', '\r', '\n'))); m = m.NextMatch(); } // Build the part tree. // This is a container part. if (part.ContentType.Type.ToLower().Equals("multipart")) { Parser.ParseSubParts(ref part, message); } // This is a nested message. else if (part.ContentType.Type.ToLower().Equals("message")) { // TODO } // This is a leaf of the part tree // Check necessary for single part emails (fix from alex294 on CodePlex) // Why would we consider the body only to the first string? Doesn't make sense - and fails //else if (part.ContentType.Type.ToLower().Equals("text")) //{ // int BodyEnd = body.IndexOf(' '); // if (BodyEnd > 0) // { // part.TextContent = body.Substring(0, BodyEnd); // } //} DecodePartBody(ref part); try { BodyParsed(null, message); } catch (Exception) { // event is not supported. } } } catch (Exception ex) { throw new ParsingException(ex.Message); } return(part); }