I need to send some text in html by email. But I need to do it not in the email body but in the attachment. I use this code snippet to form an attachment:
public MailMessage GetMailMessage(string @from)
{
var m = new MailMessage(new MailAddress(@from), new MailAddress(_to)) {Subject = _subj};
var attach = new Attachment(new MemoryStream(
Encoding.UTF8.GetBytes(_htmlAttach)), _subj + ".html", MediaTypeNames.Text.Html);
attach.ContentDisposition.Inline = false;
attach.ContentType.Name = _subj + ".html";
m.Attachments.Add(attach);
return m;
}
But when I send such an email to my gmail mailbox i recieve a plain-text message with smth like this in text:
\ =?utf-8?B?dDlDd0lOQy8wTFhSZ05DNDBMN1F0Q0F4Pz0NCiA9P3V0Zi04P0I/TXpv?=\ \ =?utf-
8?B?ME5pQXlPUzR3T0M0eU1ERXhJQzBnTVRRNk1qQWdNamt1TURndU1qQXhN?=\ \ =?utf-8?B?UzVvZEcxcz89?="
Content-Transfer-Encoding: base64 Content-Disposition: attachment
PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEvL0VO
IiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvc3RyaWN0LmR0ZCI+DQo8aHRt
bCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgeG1sOmxhbmc9 ImVuIj4NCjxoZWFkPg0KI
What is the right way to send a html-file in attach?
UPD:Here is the raw mail message part:
MIME-Version: 1.0
From: <xxx@xxx.xx>
To: xxx@gmail.com
Date: Mon, 29 Aug 2011 03:29:05 -0700 (PDT)
Subject: xxx
Content-Type: multipart/mixed; boundary=--boundary_0_c99e5172-1766-4cfe-a6e0-7f6b0fa11061
----boundary_0_c99e5172-1766-4cfe-a6e0-7f6b0fa11061
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: quoted-printable
----boundary_0_c99e5172-1766-4cfe-a6e0-7f6b0fa11061
Content-Type: text/html;
name="=?utf-8?B?PT91dGYtO开发者_JS百科D9CPzBLUFFzdEMxMExUUXZ0QzgwTHZRdGRDOTBMalF0U0RR?=\
\
=?utf-8?B?dDlDd0lOQy8wTFhSZ05DNDBMN1F0Q0F4Pz0NCiA9P3V0Zi04P0I/TXpv?=\
\
=?utf-8?B?ME5pQXlPUzR3T0M0eU1ERXhJQzBnTVRRNk1qQWdNamt1TURndU1qQXhN?=\
\
=?utf-8?B?UzVvZEcxcz89?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment
Then goes the base64 text:
PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEvL0VO
IiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvc3RyaWN0LmR0ZCI+DQo8aHRt
bCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgeG1sOmxhbmc9
ImVuIj4NCjxoZWFkPg0KICAgIDxtZXRhIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hh
And in the end:
----boundary_0_c99e5172-1766-4cfe-a6e0-7f6b0fa11061--
Looks like you are lacking newlines between the generated parts. So you need to put in something like "To: " + newMailAddress(to) + "\n"
etc. You will also need to build the container MIME structure. If you don't have any actual message, just send the HTML as a single body part, rather than as an "attachment". Something like this
From: me <self@example.net>
To: you <guy@example.com>
Subject: here
MIME-Version: 1.0
Content-type: text/html; name="=?utf-8?q?really_bewildering?=
=?utf-8?q?_long_name.html?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="=?utf-8?q?really_bewildering?=
=?utf-8?q?_long_name.html?="
PCFET0NUWVBFIGh0bWwgUFVCTElDICItL ...
The example message you pasted, which moves wraps the body inside a single-part multipart/related structure, is completely equivalent.
I believe the filename= part in Content-Disposition is the correct place to put the file name, but for backwards compatibility with very old clients, you're best off putting it in both places.
Note the correct way of wrapping a long header line: there should not be backslashes before the newline; rather, indent the follow-on line with at least one whitespace character. There should be no empty lines in the headers (the empty line is what separates the headers from the body; so the first empty line in your erroneous headers is what pushes the rest of your headers into the body).
What's with the base64 encoding everywhere? Unless your document is heavy on 8-bit content, it's probably both smaller and easier to debug if you use quoted-printable instead. You'll notice I changed the file name to quoted-printable just to make it easier to read; you could do the same with the actual attachment's contents, too.
Update: Added Content-Disposition and file name as well as comments below sample message.
Emphasis: The immediate problem is your incorrect wrapping of the multi-line filename in the MIME headers.
instead of putting the bytes into a memory stream why don't you put the text?
I think you could use another overload of new Attachment()
and specify the content in another way.
if you have already a file stored somewhere you can attach the file or you can use a StreamReader / TextReader combination to make sure you push text data and not binary data into the attachmentz content.
Use either SevenBit
(only up to 1000 characters!) or QuotedPrintable
as TransferEncoding
for the attachment.
Your attachment type is funky. For someone just wanting to send UTF8 (standard text) one has to specify the attachment content type. That requires one to Stream
it in, instead of passing a string.
Example With a list of html text(s)
System.Net.Mime.ContentType ct
= new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Text.Html);
HtmlAttachments.Select( str => new Attachment(str.ToStream(), ct))
.ToList()
.ForEach( html => mailMessage.Attachments.Add(html));
... {Usual loading of to/from etc }
client.Send(mailMessage);
For completeness here is the ToStream
extensions:
public static Stream ToStream( this string value ) => ToStream(value, Encoding.UTF8);
public static Stream ToStream( this string value, Encoding encoding )
=> new MemoryStream(encoding.GetBytes(value ?? string.Empty));
精彩评论