Tom Fobear
Tom Fobear

Reputation: 6749

Multipart E-mail Using MailMessage

I have an E-mail I want to send from C# which has a vCalendar and an HTML body parts.

I created a MailMessage, and set 2 alternate views:

AlternateView avCal  = new AlternateView("VCALENDAR:...", null, "text/calendar");
AlternateView avHtml = new AlternateView("<p>some html</p>", null, "text/html");

mailMessage.AlternateViews.Add(avCal);
mailMessage.AlternateViews.Add(avHtml);

This gives me a message with a Content-Type of multipart/alternative.

This will show both the calendar appointment and HTML part on my webmail but not Outlook.

How can I show two different parts like this with different content types? What I'm looking for is more like a Content-Type: multipart/mixed where both "Alternate Views" show up.

EDIT

When I use @Chris Haas's method, I get close but the markup is not rendered. It seems to be ignoring MailMessage.IsBodyHtml = true

html not showing up

not really sure how to view it raw in outlook but just the headers...

Return-Path: <*****@****.com>
X-Footer: ZWJyaWRnZS5jb20=
Received: from localhost ([127.0.0.1])
    by mail.foo.com
    for *****@****.com;
    Wed, 2 Jan 2013 17:20:14 -0500
MIME-Version: 1.0
From: "George Washington" <*****@****.com>
To: "George Washington" <*****@****.com>
Date: 2 Jan 2013 17:29:14 -0500
Subject: To-Do: test test - test
Content-Type: multipart/mixed; 
boundary=--boundary_0_4fbc08b4-2198-45b1-bf2e-9659179aad84

Upvotes: 6

Views: 9309

Answers (5)

I had the same problem.

Try adding two AlternateViews to MailMessage, one with content type text/calendar, with ics file, one with content type text/html, with email body.

Worked for me :)

Upvotes: 1

HansLindgren
HansLindgren

Reputation: 369

None of these suggestions works for me.

Closest I've got, so far, is to attach a MemoryStream with "text/calendar" as the MIME type. However, GMail does not recognize this file in the sense that it does not Display the summary from the .ICS file, neither does it allow me to 'Add to Calendar'.

However, when I forward the exact same email to myself (or others) on GMail, GMail DOES display the .ICS content. I am going crazy here trying to test different solutions.

Upvotes: 0

shawad
shawad

Reputation: 355

I had the same issue; I could not get the invite to display the HTML without displaying the tags. I was able to solve the issue with something similiar to (variable f contains all the "BEGIN:VCALENDAR" stuff):

System.Net.Mime.ContentType calendarType = new System.Net.Mime.ContentType("text/calendar");
AlternateView ICSview = AlternateView.CreateAlternateViewFromString(f.ToString(), calendarType);
AlternateView HTMLV = AlternateView.CreateAlternateViewFromString(body, new System.Net.Mime.ContentType("text/html"));
MailMessage email = new MailMessage("[email protected]", "[email protected]", "subject", "body");
email.AlternateViews.Add(ICSview);
email.AlternateViews.Add(HTMLV);
SmtpClient client = new SmtpClient();
client.Send(email);

I am sure the code could be tidied...

Upvotes: 1

Chris Haas
Chris Haas

Reputation: 55457

Try sending the VCALENDAR as an Attachment with the Inline attribute set to true:

using (MailMessage mm = new MailMessage("...", "...", "Subject here", "Body here")) //Pick whatever constructor you want
{
    using (Attachment a = new Attachment("c:\\test.ics", "text/calendar")) //Either load from disk or use a MemoryStream bound to the bytes of a String
    {
        a.Name = "meeting.ics";                         //Filename, possibly not required
        a.ContentDisposition.Inline = true;             //Mark as inline
        mm.Attachments.Add(a);                          //Add it to the message
        using (SmtpClient s = new SmtpClient("..."))    //Send using normal
        {
            s.Send(mm);
        }
    }
}

EDIT

Okay, I've updated the code to not rely on a file, so that we're using the exact same ICS file. Update the strings at the top and the SmtpClient if needed but otherwise leave the code exactly as is. The ICS is from the middle of this page.

  String mailFrom = "[email protected]";
  String mailTo = "[email protected]";
  String mailSubject = "This is a test";
  String mailBody = "<p><strong>Hello</strong> world</p>";
  String smtpServer = "mail.example.com";

  using (var mm = new MailMessage()) //Pick whatever constructor you want
  {
      mm.To.Add(mailFrom);
      mm.From = new MailAddress(mailTo);
      mm.Subject = mailSubject;
      mm.Body = mailBody;
      mm.IsBodyHtml = true;
      String t = "BEGIN:VCALENDAR\r\n" +
                 "METHOD:REQUEST\r\n" +
                 "BEGIN:VEVENT\r\n" +
                 "DTSTAMP:20080325T202857Z\r\n" +
                 "DTSTART:20080325T200000Z\r\n" +
                 "DTEND:20080325T220000Z\r\n" +
                 "SUMMARY:Test meeting request\r\n" +
                 "UID:040000008200E00074C5B7101A82E00800000000B2BB07349575C80100000000000000001000000019BF8D0149C50643A81325C54140C093\r\n" +
                 "ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=\"Dan\":MAIL\r\n" +
                 " TO:[email protected]\r\n" +
                 "ORGANIZER;CN=\"Administrator\":MAILTO:[email protected]\r\n" +
                 "LOCATION: Here\r\n" +
                 "DESCRIPTION:Test Request\r\n" +
                 "SEQUENCE:0\r\n" +
                 "PRIORITY:5\r\n" +
                 "CLASS:\r\n" +
                 "CREATED:20080321T190958Z\r\n" +
                 "STATUS:CONFIRMED\r\n" +
                 "TRANSP:OPAQUE\r\n" +
                 "END:VEVENT\r\n" +
                 "END:VCALENDAR";
      Byte[] bytes = System.Text.Encoding.ASCII.GetBytes(t);
      using (var ms = new System.IO.MemoryStream(bytes))
      {
          using (var a = new Attachment(ms, "meeting.ics", "text/calendar")) //Either load from disk or use a MemoryStream bound to the bytes of a String
          {
              a.ContentDisposition.Inline = true;             //Mark as inline
              mm.Attachments.Add(a);                          //Add it to the message
              using (SmtpClient s = new SmtpClient(smtpServer))    //Send using normal
              {
                  s.Send(mm);
              }
          }
      }

  }

Upvotes: 6

Nicholas Carey
Nicholas Carey

Reputation: 74355

I believe you have to send your vCalendear (*.vcs) or iCalendar (*.ics) file as an attachment for Outlook to know what to do with it.

The recipient will then need to open the email in Outlook and double-click the attachment to import it into the Outlook/Exchange calendar.

Upvotes: 2

Related Questions