2013-04-05 32 views
9

Tôi đang sử dụng Amazon SES SendRawEmail API vì thế tôi cần một MailMessage làm bộ nhớ.C# MailMessage để phát trực tuyến - sự cố mã hóa

Tôi đã tìm thấy một số câu trả lời cho vấn đề MailMessage to MemoryStream ở đây trên stackoverflow.

Giải pháp 1: Sử dụng một trong đó sử dụng phương pháp riêng nó kết quả trong mã hóa sai của các bộ phận của email: https://stackoverflow.com/a/8826833

Giải pháp 2: Không có vấn đề Encoding sử dụng giải pháp này, nơi bạn gửi cho một pickup và sau đó đọc lại: https://stackoverflow.com/a/14350088

Tôi rất không thích thực tế là tôi cần ghi vào tệp tạm thời để thực hiện công việc này một cách chính xác. Có ai có bất kỳ ý tưởng làm thế nào các giải pháp MemoryStream tinh khiết có thể mess up một số mã hóa.

Các mail iam thử nghiệm với là thế này:

var mailMessage = new MailMessage(); 
mailMessage.Subject = "HEADER WITH SPECIAL ÆØÅ"; 
mailMessage.Body = "TEST"; 

Attachment att = new Attachment(@"C:\AttachmentWithSpecial ÆØÅ.pdf"); 
mailMessage.Attachments.Add(att); 
mailMessage.From = new MailAddress("[email protected]", "NameÆØÅ"); 
mailMessage.To.Add(new MailAddress("[email protected]", "NameÆØÅ")); 

Để tóm tắt:

  • Nếu tôi gửi thông điệp này với SMTP tiêu chuẩn có vẻ tốt.
  • Nếu tôi gửi nó bằng cách sử SendRawEmail có vẻ tốt nếu tôi tạo ra MemoryStream bằng cách sử dụng giải pháp 2
  • Nếu tôi gửi nó bằng cách sử SendRawEmail nó có vấn đề mã hóa nếu tôi tạo ra MemoryStream bằng cách sử dụng giải pháp 1.

với các vấn đề mã hóa tôi có nghĩa là 'ø' hiển thị như

enter image description here

+0

Tại sao bạn không sử dụng SendEmail? SES cho phép bạn soạn email và nó hỗ trợ mã hóa. –

+0

Như tôi thấy nó không hỗ trợ tệp đính kèm. ? –

+0

Ồ vâng, bạn đã thử sử dụng StringWriter chưa? Memory Stream có thể bỏ qua mã hóa vì nó sử dụng byte làm dung lượng lưu trữ. –

Trả lời

1

bạn đã cố gắng một cách rõ ràng cụ thể mã hóa cho Tiêu đề/Body và MailAddress?

Tôi đoán rằng khi NET viết mail vào thư mục nó có thể bằng cách nào đó để xác định mã hóa đúng (hoặc có thể File Reader bằng cách nào đó có thể tìm thấy mã hóa đúng để chuyển đổi dữ liệu). Và trong bộ nhớ tất cả mọi thứ là trong mã hóa mặc định, mà không làm việc cho bạn.

+0

Ya tôi đã thử rằng tuy nhiên NET tôi thực sự rất thông minh về việc thiết lập này để UTF-8 khi cần thiết. Trong hàm khởi tạo của địa chỉ email để khôi phục bạn tìm thấy: this.displayNameEncoding = displayNameEncoding ?? Encoding.GetEncoding ("utf-8"); Điều đó có nghĩa là nếu bạn không xác định mã hóa, nó sẽ mặc định là UTF-8. Trong tập hợp chủ đề và nội dung, chúng có mã kiểm tra xem chuỗi có chứa ascii hay không, nếu không nó sẽ cố gắng tự mã hóa. Vì vậy, nếu bạn làm mail.Subject = "æøå"; và sau đó kiểm tra thư.SubjectEncoding nó sẽ chính xác đã được UTF-8 –

0
message.BodyEncoding = message.SubjectEncoding = message.HeadersEncoding = Encoding.UTF8; 
0

Thật không may là đối tượng MailMessage bị lỗi và có giao diện kém.

Điều tốt là .NET 4.5 phần cố định nó với allowUnicode cờ trong Gửi() (không may Gởi phương pháp vẫn còn tư nhân)

Dưới đây là biến dạng "Giải pháp 1". Mã hóa theo chủ đề giống như "Giải pháp 2". Chỉ .NET Framework 4.5.

private static MemoryStream ConvertMailMessageToMemoryStream(MailMessage message) 
{ 
    Assembly systemAssembly = typeof(SmtpClient).Assembly; 
    Type mailWriterType = systemAssembly.GetType("System.Net.Mail.MailWriter"); 
    const BindingFlags nonPublicInstance = BindingFlags.Instance | BindingFlags.NonPublic; 
    ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(nonPublicInstance, null, new[] typeof(Stream) }, null); 

    MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", nonPublicInstance); 
    MethodInfo closeMethod = mailWriterType.GetMethod("Close", nonPublicInstance); 
    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
     object mailWriter = mailWriterContructor.Invoke(new object[] { memoryStream }); 
     //AssertHelper.IsTrue(sendMethod.GetParameters().Length > 2, ".NET framework must be 4.5 or higher in order to properly encode email subject."); 
     sendMethod.Invoke(message, nonPublicInstance, null, 
      new[] { mailWriter, true, false }, 
      null); 
     closeMethod.Invoke(mailWriter, nonPublicInstance, null, new object[] { }, null); 
     return memoryStream; 
    } 
} 
Các vấn đề liên quan