2014-06-11 2 views
3

MailKit 라이브러리를 사용하여 잘 작동하는 전자 메일을 처리하고 있습니다. 그러나 전자 메일을 구성 파일로 분할하려고합니다. a) 기본 전자 메일 (첨부 파일 없음) b) 개별 첨부 파일, 파일 시스템에 저장합니다.MailKit/MimeKit을 사용하여 전자 메일에서 첨부 파일 제거하기

첨부 파일을 개별적으로 저장할 수는 있지만 전자 메일 본문 코드에서 첨부 파일을 제거 할 수 없습니다. 나는. 주요 이메일과 함께 저장되므로 데이터가 복제됩니다. :/

나는 시도했다 :

foreach (MimePart part in inMessage.BodyParts) 
{ 
    if (part.IsAttachment) 
    { 
     // Remove MimePart < This function isn't available on the collection. 
    } 
} 

도 시도 해 봤나 : 사람이 도움을 줄 수있는 경우

var builder = new BodyBuilder(); 
foreach (MimePart part in inMessage.BodyParts) 
{ 
    if (!part.IsAttachment) 
    { 
     // Add MimeParts to collection < This function isn't available on the collection. 
    } 
} 
outMessage.Body = builder.ToMessageBody(); 

, 나는 많은 거라고를 주셔서 감사합니다.

솔루션 참고 구현 :

private List<string> GetAttachments(string outDirPath) 
     { 
      MimeMessage message = (Master as fsEmail).GetMimeMessage(); 

      List<string> list = new List<string>(); 
      foreach (MimePart attachment in message.Attachments) 
      { 
       using (var cancel = new System.Threading.CancellationTokenSource()) 
       { 
        string filePath = outDirPath + Guid.NewGuid().ToString() + Path.GetExtension(attachment.FileName); 
        using (var stream = File.Create(filePath)) 
        { 
         attachment.ContentObject.DecodeTo(stream, cancel.Token); 
         list.Add(filePath); 
        } 
       } 
      } 
      return list; 
     } 
+0

이 유용 http://www.limilabs.com/blog/download-email-attachments-net –

+0

감사가 될 수 있지만,이 링크를 기반으로 이렇게하려면, 당신의 코드는 다음과 같을 것 Mail.dll 그리고 나는 이상적으로 MailKit을 고수하고 싶다. – FrugalTPH

+1

FWIW, 디스크에 첨부 파일 저장을 취소 할 계획이 아니라면 취소 토큰을 만들 필요가 없습니다. CancellationToken.None을 사용하거나 취소 토큰을 전혀 전달하지 않을 수 있습니다. – jstedfast

답변

5

당신은 첨부 파일 https://github.com/jstedfast/MimeKit/blob/master/MimeKit/MimeMessage.cs#L734 모든 MimePart의를 검색 한 후 모든 Multipart의 반복과 https://github.com/jstedfast/MimeKit/blob/master/MimeKit/Multipart.cs#L468를 호출 할 수 있습니다

private string GetMimeMessageOnly(string outDirPath) 
     { 
      MimeMessage message = (Master as fsEmail).GetMimeMessage(); 

      if (message.Attachments.Any()) 
      { 
       var multipart = message.Body as Multipart; 
       if (multipart != null) 
       { 
        while (message.Attachments.Count() > 0) 
        { 
         multipart.Remove(message.Attachments.ElementAt(0)); 
        } 
       } 
       message.Body = multipart; 
      } 

      string filePath = outDirPath + Guid.NewGuid().ToString() + ".eml"; 
      Directory.CreateDirectory(Path.GetDirectoryName(outDirPath)); 
      using (var cancel = new System.Threading.CancellationTokenSource()) 
      {  
       using (var stream = File.Create(filePath)) 
       { 
        message.WriteTo(stream, cancel.Token); 
       } 
      } 
      return filePath; 
     } 

만 첨부 얻을 수 첨부 파일을 제거하십시오.

아래 샘플은 메일에 대해 몇 가지 가정을합니다. 하나만 있습니다 Multipart 일부 이메일 클라이언트 (Outlook)는 메일 작성 방법이 매우 독창적입니다.

static void Main(string[] args) 
{ 
    var mimeMessage = MimeMessage.Load(@"x:\sample.eml"); 
    var attachments = mimeMessage.Attachments.ToList(); 
    if (attachments.Any()) 
    { 
     // Only multipart mails can have attachments 
     var multipart = mimeMessage.Body as Multipart; 
     if (multipart != null) 
     { 
      foreach(var attachment in attachments) 
      { 
       multipart.Remove(attachment); 
      } 
     } 
     mimeMessage.Body = multipart; 
    } 
    mimeMessage.WriteTo(new FileStream(@"x:\stripped.eml", FileMode.CreateNew)); 
} 
+0

아, 이것이 내가 컬렉션에 대해 기대하는 방식으로 추가 및 제거 메소드가 표시되지 않는 이유 일 수 있습니다. MimeEntity로 캐스팅했다고 생각합니다. 아마 Multipart가 필요합니다. 내일 이걸 시험해 볼게. – FrugalTPH

0

Mailkit을 사용하여 전자 메일과 첨부 파일을 다운로드하는 응용 프로그램을 만들었습니다. 첨부 파일이있는 iOS에서 보낸 전자 메일이 올바르게 처리되지 않았습니다. MailKit은 이미지를 첨부 파일 목록에 추가하지 않았습니다.

foreach (var attachment in message.BodyParts.Where(bp => !string.IsNullOrEmpty(bp.FileName))) 
{ 
    if (attachment.FileName.ToLowerInvariant().EndsWith(".jpg")) 
    { 
     //do something with the image here 
    } 
} 
+0

HTML과 일반 텍스트의 차이점은 무엇입니까? 저는 MailKit이 .eml 확장자를 가진 MimeMessage.WriteTo (file)을 할 때 저에게 좋은 일을하기 때문에 묻습니다.이러한 파일은 Outlook에서 뷰어로 잘 렌더링되며,이를 유지하고 싶지만 .eml을 저장하기 전에 MimeTree에서 첨부 파일을 제거하면됩니다. – FrugalTPH

+0

좋아, 내가 처음에는 귀하의 요구 사항을 얻지 못한 것 같습니다. 나는 .eml을 저장하지 않았지만 데이터베이스에 텍스트를 저장했습니다. 그리고 나는 그 텍스트를 얻기 원했습니다. 그래서 Andreas의 대답은 당신이 찾고있는 것보다 더 많은 것 같습니다. 그러나 언급했듯이 : iOS 장치에서 사진을 보내고 .eml에서 의도 한대로 제거 할 것인지 확인하십시오. 어쩌면 두 번째 코드 스 니펫이 이미지를 제거하는 데 도움이 될지도 모릅니다. – pastrami01

+2

FWIW, MimeKit은 MimeMessage.Attachments 속성에 "attachment"(+ 모든 매개 변수) 값이있는 Content-Disposition 헤더가있는 부분 만 나열합니다. 이것은 다른 의미가 비표준이기 때문입니다. iOS에는 Content-Disposition 헤더가 없거나 값을 "인라인"또는 그 밖의 값으로 설정합니다. – jstedfast

4

MimeKit 0.38로 시작 :

private static string GetPlainTextFromMessageBody(MimeMessage message) 
    { 
     //content type needs to match text/plain otherwise i would store html into DB 
     var mimeParts = message.BodyParts.Where(bp => bp.IsAttachment == false && bp.ContentType.Matches("text", "plain")); 
     foreach (var mimePart in mimeParts) 
     { 
      if (mimePart.GetType() == typeof(TextPart)) 
      { 
       var textPart = (TextPart)mimePart; 
       return textPart.Text; 
      } 
     } 
     return String.Empty; 
    } 

이 내가 단지 .JPG 파일을 다운로드하는 데 사용되는 방법은 다음과 같습니다

나는 메시지의 텍스트를 얻기 위해이 방법을 사용했다. 0.0, 당신은 제거하려는 첨부 파일의 목록을 수집 할 MIME 트리 구조를 통과하는 MimeIterator을 사용할 수 (및 제거)합니다.

var attachments = new List<MimePart>(); 
var multiparts = new List<Multipart>(); 
var iter = new MimeIterator (message); 

// collect our list of attachments and their parent multiparts 
while (iter.MoveNext()) { 
    var multipart = iter.Parent as Multipart; 
    var part = iter.Current as MimePart; 

    if (multipart != null && part != null && part.IsAttachment) { 
     // keep track of each attachment's parent multipart 
     multiparts.Add (multipart); 
     attachments.Add (part); 
    } 
} 

// now remove each attachment from its parent multipart... 
for (int i = 0; i < attachments.Count; i++) 
    multiparts[i].Remove (attachments[i]); 
관련 문제