Modifying the content type of an attachment in a CDO.Message object

content-type, email, email-attachments, mhtml, vbscript

Solution

So your problem is that at least some email clients save MHTML attachment incorrectly if content type for the attachment is set as `content-type="message/rfc822"`.

First, it is worth noting that your analysis of a root cause of the issue is flawed. You appear to be confused by where `multipart/related` MIME type comes into play. As a matter of fact, RFC 2557 does NOT state that body part corresponding to MHTML attachment must have `content-type="multipart/related"`. Instead, MIME multipart/related is internal structure of MHTML file itself. Quoting Wikipedia article:

The content of an MHTML file is encoded as if it were an HTML e-mail message, using the MIME type multipart/related.

I.e. if you open MHTML file with text editor, you should see the following:

Content-Type: multipart/related; ...

Microsoft states that MHTML files should be served with `content-type="message/rfc822"` in KB937912. This is exactly what CDO does by default when you attach such file via `AddAttachment` method. I believe such behavior does not contradict RFC 2557 in any way. As per the RFC:

There are a number of document formats... that specify documents consisting of a root resource and a number of distinct subsidiary resources referenced by URIs within that root resource. There is an obvious need to be able to send such multi-resource documents in e-mail [SMTP], [RFC822] messages.

The standard defined in this document specifies how to aggregate such multi-resource documents in MIME-formatted [MIME1 to MIME5] messages for precisely this purpose.

To recap, you definitely should not set content type of MHTML attachment to `multipart/related`.

While `message/rfc822` seems to be the way to use with MHTML files, it obviously triggers the problem you described in the question. I tested with Outlook 2010 and OWA 2010, and was able to reproduce it.

Alternative content types that are used by various email clients for MHTML attachments are `application/octet-stream` and `application/x-mimearchive`. These two didn't exhibit the problem in my tests.

Problem

When I try to add an MHTML file as an attachment to an email message in VBScript, the `ContentMediaType` is incorrectly set to `"message/rfc822"` (RFC 822). From what I understand, this is correct according to Microsoft, but is incorrect according to RFC 2557 which states that it should be `"multipart/related"`. This is a problem, because most (if not all) mail clients interpret `"message/rfc822"` as an email message. Since the file extensions `".mht"` and `".mhtml"` do not match any valid file extension of an email message, the mail client appends one of `".msg"`, `".eml"`, etc. to the filename. When a user opens the attachment, it opens as an email message and doesn't display correctly since an MHTML file and an email message are saved differently. ``` Sub SendEmail(FromAddress, ToAddress, Subject, Body, Attachment) Call Err.Clear On Error Resume Next Schema = "http://schemas.microsoft.com/cdo/configuration/" Set Configuration = Sys.OleObject("CDO.Configuration") Configuration.Fields.Item(Schema + "sendusing") = 2 Configuration.Fields.Item(Schema + "smtpserver") = SMTPServer Configuration.Fields.Item(Schema + "smtpserverport") = 25 Configuration.Fields.Item(Schema + "smtpauthenticate") = 1 ' Configuration.Fields.Item(schema + "sendusername") = "" ' Configuration.Fields.Item(schema + "sendpassword") = "" Call Configuration.Fields.Update Set Message = Sys.OleObject("CDO.Message") Set Message.Configuration = Configuration Message.From = FromAddress Message.To = ToAddress Message.Subject = Subject Message.HTMLBody = Body If Not IsEmpty(Attachment) Then 'CDO.Message.AddAttachment doesn't set the correct content media type for an MHTML file. Call Message.AddAttachment(Attachment) End If Call Message.Send End Sub ``` When I run this code, `Message.Attachments.Item(1).ContentMediaType` is set to `"message/rfc822"`. I need it to be `"multipart/related"` if `Attachment` (a string) ends with `".mht"` or `".mhtml"` (case-insensitive). I can do this with the following code. ``` If Len(Attachment) >= 4 And InStr(Len(Attachment) - 3, Attachment, ".mht", vbTextCompare) Or Len(Attachment) >= 4 And InStr(Len(Attachment) - 5, Attachment, ".mhtml", vbTextCompare) Then Message.Attachments.Item(1).ContentMediaType = "multipart/related" End If ``` For some unknown reason, this undefines the attachment from `Message.Attachments`. I've looked at manually adding the attachment per these instructions, but when I call `Message.Attachments.Item(1).Fields.Update`, the object becomes undefined. I think setting the attachments's `ContentMediaType`, implicitly invokes it's `Fields`'s `Update` method which is what I think is responsible for this unexpected behavior. How can I get around this and send an MHTML file with the `"multipart/related"` content type while maintaining the proper file extension?

Original source

Related problems