title: Attaching a file to an iCalendar
body: <p>I have iCalendar meeting requests sending correctly via SMTP (using the code below), but when I attempt to attach a file, the file does not appear as part of the iCalendar. When saving out the .ics after opening it in outlook, the whole file data has been stripped out.</p>
  <p>Here's the code I'm using:</p>
  <pre><code>System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
  msg.From = new System.Net.Mail.MailAddress(&quot;test1@test.com&quot;, &quot;test1&quot;);
  msg.To.Add(new System.Net.Mail.MailAddress(&quot;test2@test.com&quot;, &quot;test2&quot;));
  msg.Subject = &quot;Subject1&quot;;
  msg.Body = &quot;Body line 1\r\nBody line 2\r\nBody line 3&quot;;
  
  System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType(&quot;text/calendar&quot;);
  ct.Parameters.Add(&quot;method&quot;, &quot;REQUEST&quot;);
  ct.Parameters.Add(&quot;name&quot;, &quot;meeting.ics&quot;);
  
  System.Text.StringBuilder sb = new System.Text.StringBuilder();
  sb.AppendLine(&quot;BEGIN:VCALENDAR&quot;);
  
  sb.AppendLine(&quot;PRODID:-/Microsoft Corporation//Outlook 15.0 MIMEDIR//EN&quot;);
  sb.AppendLine(&quot;VERSION:2.0&quot;);
  sb.AppendLine(&quot;METHOD:REQUEST&quot;);
  sb.AppendLine(&quot;X-MS-OLK-FORCEINSPECTOROPEN:TRUE&quot;);
  
  sb.AppendLine(&quot;BEGIN:VEVENT&quot;);
  
  string file = &quot;D:\\LoadedDate.xlsx&quot;;
  string filename = Path.GetFileName(file);
  
  sb.Append(&quot;ATTACH;ENCODING=BASE64;VALUE=BINARY;X-FILENAME=&quot;);
  sb.Append(filename).Append(&quot;:&quot;).AppendLine(Convert.ToBase64String(File.ReadAllBytes(file), Base64FormattingOptions.InsertLineBreaks));
  
  foreach (System.Net.Mail.MailAddress to in msg.To)
  {
      sb.AppendLine(String.Format(&quot;ATTENDEE;CN=\&quot;{0}\&quot;;RSVP=TRUE:mailto:{1}&quot;, String.IsNullOrEmpty(to.DisplayName) ? to.Address : to.DisplayName, to.Address));
  }
  sb.AppendLine(&quot;CLASS:PUBLIC&quot;);
  sb.Append(&quot;CREATED:&quot;).AppendLine(DateTime.Now.ToUniversalTime().ToString(&quot;yyyyMMdd\\THHmmss\\Z&quot;));
  sb.Append(&quot;DESCRIPTION:&quot;).Append(msg.Body.Replace(&quot;\r\n&quot;, &quot;\\n&quot;)).Append(&quot;\\n &lt;&lt;&quot;).Append(filename).AppendLine(&quot;&gt;&gt; \\n&quot;);
  
          string dt = DateTime.Now.AddHours(1).ToUniversalTime().ToString(&quot;yyyyMMdd\\THHmmss\\Z&quot;);
          sb.AppendLine(&quot;DTSTART:&quot; + dt);
          sb.AppendLine(&quot;DTSTAMP:&quot; + dt);
          sb.AppendLine(&quot;DTEND:&quot; + DateTime.Now.AddHours(5).ToUniversalTime().ToString(&quot;yyyyMMdd\\THHmmss\\Z&quot;));
          sb.AppendLine(&quot;LAST-MODIFIED:&quot;);
          sb.Append(&quot;LOCATION:&quot;).AppendLine(&quot;Location1&quot;);
          sb.AppendLine(String.Format(&quot;ORGANIZER;CN=\&quot;{0}\&quot;:mailto:{0}&quot;, msg.From.Address));
          sb.AppendLine(&quot;PRIORITY:5&quot;);
          sb.AppendLine(&quot;SEQUENCE:0&quot;);
          sb.Append(&quot;SUMMARY;LANGUAGE=en-gb:&quot;).AppendLine(msg.Subject);
          sb.AppendLine(&quot;TRANSP:OPAQUE&quot;);
  
          // UID should be unique.
          sb.Append(&quot;UID:&quot;).AppendLine(Guid.NewGuid().ToString());
          sb.Append(&quot;X-ALT-DESC;FMTTYPE=text/html:&lt;!DOCTYPE HTML PUBLIC \&quot;-//W3C//DTD HTML 3.2//EN\&quot;&gt;\\n&quot;);
          sb.Append(&quot;&lt;HTML&gt;\\n&quot;).Append(&quot;&lt;HEAD&gt;\\n&quot;).Append(&quot;&lt;META HTTP-EQUIV=\&quot;Content-Type\&quot; CONTENT=\&quot;text/html\\; charset=iso-8859-1\&quot;&gt;\\n&quot;).Append(&quot;&lt;META NAME=\&quot;Generator\&quot; CONTENT=\&quot;MS Exchange Server version 14.03.0162.000\&quot;&gt;\\n&quot;);
          sb.Append(&quot;&lt;TITLE&gt;&quot;).Append(msg.Subject).Append(&quot;&lt;/TITLE&gt;\\n&quot;);
          sb.Append(&quot;&lt;/HEAD&gt;\\n&quot;).Append(&quot;&lt;BODY&gt;\\n&quot;).Append(&quot;&lt;!--Converted from text/rtf format --&gt;\\n\\n&quot;);
          sb.Append(&quot;&lt;P DIR=LTR&gt;&lt;SPAN LANG=\&quot;en-gb\&quot;&gt;&lt;FONT FACE=\&quot;Calibri\&quot;&gt;&quot;).Append(msg.Body.Replace(&quot;\r\n&quot;, &quot;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;\\n\\n&lt;P DIR=LTR&gt;&lt;SPAN LANG=\&quot;en-gb\&quot;&gt;&lt;FONT FACE=\&quot;Calibri\&quot;&gt;&quot;)).Append(&quot;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;\\n\\n&quot;);
          sb.Append(&quot;&lt;P DIR=LTR&gt;&lt;SPAN LANG=\&quot;en-gb\&quot;&gt;&lt;FONT FACE=\&quot;Arial\&quot; SIZE=2 COLOR=\&quot;#000000\&quot;&gt; &amp;lt\\;&amp;lt\\;&quot;).Append(filename).Append(&quot;&amp;gt\\;&amp;gt\\; &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;\\n\\n&quot;);
          sb.Append(&quot;&lt;/BODY&gt;\\n&quot;).AppendLine(&quot;&lt;/HTML&gt;&quot;);
  
          sb.AppendLine(&quot;X-MICROSOFT-CDO-BUSYSTATUS:BUSY&quot;);
          sb.AppendLine(&quot;X-MICROSOFT-CDO-IMPORTANCE:1&quot;);
          sb.AppendLine(&quot;X-MICROSOFT-DISALLOW-COUNTER:FALSE&quot;);
          sb.AppendLine(&quot;X-MS-OLK-AUTOFILLLOCATION:FALSE&quot;);
          sb.AppendLine(&quot;X-MS-OLK-AUTOSTARTCHECK:FALSE&quot;);
          sb.AppendLine(&quot;X-MS-OLK-CONFTYPE:0&quot;);
          sb.AppendFormat(&quot;X-MS-OLK-SENDER;CN=\&quot;{0}\&quot;:mailto:{0}&quot;, msg.From.Address).AppendLine();
  
          sb.AppendLine(&quot;STATUS:TENTATIVE&quot;);
          sb.AppendLine(&quot;BEGIN:VALARM&quot;);
          sb.AppendLine(&quot;TRIGGER:-PT15M&quot;);
          sb.AppendLine(&quot;ACTION:DISPLAY&quot;);
          sb.AppendLine(&quot;DESCRIPTION:Reminder&quot;);
          sb.AppendLine(&quot;END:VALARM&quot;);
          sb.AppendLine(&quot;END:VEVENT&quot;);
  
          sb.AppendLine(&quot;END:VCALENDAR&quot;);
  
          System.Net.Mail.AlternateView av = System.Net.Mail.AlternateView.CreateAlternateViewFromString(sb.ToString(), ct);
  
          msg.AlternateViews.Add(av);
  
          System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(&quot;mailserver&quot;);
          client.Send(msg);
  </code></pre>
  <p>I've had a look at the RFC for iCalendars (<a href="https://www.rfc-editor.org/rfc/rfc5545" rel="nofollow noreferrer">https://www.rfc-editor.org/rfc/rfc5545</a>), and I think I've done everything according to what the spec says. I'm guessing that there is either a problem with the way the file is read in (the Convert.ToBase64String bit), or I'm missing something with the alternate view (I've seen other people adding multiple views).</p>
  <p>Things I have tried:</p>
  <ul>
  <li>Replacing the Convert.ToBase64String(File.ReadAllBytes(file),
  Base64FormattingOptions.InsertLineBreaks) with
  Convert.ToBase64String(File.ReadAllBytes(file),
  Base64FormattingOptions.None).</li>
  <li>Using System.Text.Encoding
  to convert the file to BASE64 (without success).</li>
  <li>Attaching files to the email directly (using the
  MailMessage.Attachments), but that just makes the email appear as a
  normal email.</li>
  </ul>
  <p>I've also had a look at the DDay.iCal project on sourceforge (<a href="http://sourceforge.net/projects/dday-ical/" rel="nofollow noreferrer">http://sourceforge.net/projects/dday-ical/</a>), but I couldn't figure out how that worked when it came to attaching a file.</p>
  <p>One requirement I have for this is that the file has to be embedded / attached to the email, I cannot add it as a URI unfortunately.</p>
  <p>Can anyone help?</p>
  <p><strong>Update:</strong> Following arnaudq's advice, I have implemented wrapping the lines at 75 characters as mentioned in the RFC. The resulting MIME message looks like the following:</p>
  <pre><code>BEGIN:VCALENDAR
  PRODID:-//Microsoft Corporation//Outlook 15.0 MIMEDIR//EN
  VERSION:2.0
  METHOD:REQUEST
  X-MS-OLK-FORCEINSPECTOROPEN:TRUE
  BEGIN:VEVENT
  ATTACH;ENCODING=BASE64;VALUE=BINARY;X-FILENAME=test.txt:U0ZMb2dObwlTRkxvYWR
   lZERhdGUNCjkxNzY3NC8xCTI3LzExLzIwMTIgMTg6MzANCjkxMjIwNS8xCTI3LzExLzIwMTIgM
   Tg6MzANCjkxMjI0Ni8xCTI3LzExLzIwMTIgMTg6MzANCjkxMjI1Mi8xCTI3LzExLzIwMTIgMTg
   6MzANCjkxMjQyMS8xCTI3LzExLzIwMTIgMTg6MzANCjkxMjQyMi8xCTI3LzExLzIwMTIgMTg6M
   zANCjkxNTMyMS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTQzNS8xCTI3LzExLzIwMTIgMTg6MzA
   NCjkxNTU5OS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNjc3NC8xCTI3LzExLzIwMTIgMTg6MzANC
   jkxNjk1OS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNjk2MC8xCTI3LzExLzIwMTIgMTg6MzANCjk
   xNzM2Ny8xCTI3LzExLzIwMTIgMTg6MzANCjkxNzQzNC8xCTI3LzExLzIwMTIgMTg6MzANCjkxN
   DczMS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDczMi8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc
   0My8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc0NC8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc0N
   S8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc0Ni8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc2MS8
   xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc2Mi8xCTI3LzExLzIwMTIgMTg6MzANCjkxNDc2My8xC
   TI3LzExLzIwMTIgMTg6MzANCjkxNTYzNS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTYzOC8xCTI
   3LzExLzIwMTIgMTg6MzANCjkxNTY0MC8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTY0MS8xCTI3L
   zExLzIwMTIgMTg6MzANCjkxNTY1OS8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTc3Ni8xCTI3LzE
   xLzIwMTIgMTg6MzANCjkxNTc3Ny8xCTI3LzExLzIwMTIgMTg6MzANCjkxNTc3OC8xCTI3LzExL
   zIwMTIgMTg6MzANCg==
  ATTENDEE;CN=&quot;Test 1&quot;;RSVP=TRUE:mailto:test1@test.com
  CLASS:PUBLIC
  CREATED:20150318T095735Z
  DESCRIPTION:Body line 1
   Body line 2
   Body line 3
   &lt;&lt;test.txt&gt;&gt; 
  DTSTART:20150318T105735Z
  DTSTAMP:20150318T105735Z
  DTEND:20150318T145735Z
  LAST-MODIFIED:
  LOCATION:Location1
  ORGANIZER;CN=&quot;test2@test.com&quot;:mailto:test2@test.com
  PRIORITY:5
  SEQUENCE:0
  SUMMARY;LANGUAGE=en-gb:Subject1
  TRANSP:OPAQUE
  UID:40306717-c29a-42d1-b03e-0240a93c2ea2
  X-ALT-DESC;FMTTYPE=text/html:&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 3.2//E
   N&quot;&gt;&lt;HTML&gt;&lt;HEAD&gt;&lt;META HTTP-EQUIV=&quot;Content-Type&quot; CONTENT=&quot;text/html\; charse
   t=iso-8859-1&quot;&gt;&lt;META NAME=&quot;Generator&quot; CONTENT=&quot;MS Exchange Server version 1
   4.03.0162.000&quot;&gt;&lt;TITLE&gt;Subject1&lt;/TITLE&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;!--Converted from text
   /rtf format --&gt;&lt;P DIR=LTR&gt;&lt;SPAN LANG=&quot;en-gb&quot;&gt;&lt;FONT FACE=&quot;Calibri&quot;&gt;Body lin
   e 1&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P DIR=LTR&gt;&lt;SPAN LANG=&quot;en-gb&quot;&gt;&lt;FONT FACE=&quot;Calibri&quot;&gt;&lt;/
   FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;Body line 2&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P DIR=LTR&gt;&lt;SPAN LANG=&quot;en-gb&quot;
   &gt;&lt;FONT FACE=&quot;Calibri&quot;&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;Body line 3&lt;P DIR=LTR&gt;&lt;SPAN LANG=&quot;
   en-gb&quot;&gt;&lt;FONT FACE=&quot;Arial&quot; SIZE=2 COLOR=&quot;#000000&quot;&gt; &amp;lt\;&amp;lt\;test.txt&amp;gt\;&amp;
   gt\; &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;
  X-MICROSOFT-CDO-BUSYSTATUS:BUSY
  X-MICROSOFT-CDO-IMPORTANCE:1
  X-MICROSOFT-DISALLOW-COUNTER:FALSE
  X-MS-OLK-AUTOFILLLOCATION:FALSE
  X-MS-OLK-AUTOSTARTCHECK:FALSE
  X-MS-OLK-CONFTYPE:0
  STATUS:TENTATIVE
  BEGIN:VALARM
  TRIGGER:-PT15M
  ACTION:DISPLAY
  DESCRIPTION:Reminder
  END:VALARM
  END:VEVENT
  END:VCALENDAR
  </code></pre>
  <p>Unfortunately, this still doesn't work and the file (in this case a simple plain text file) does not come through with the calendar entry in Outlook.</p>
  <p>What's really interesting is that saving the above MIME message to a file manually and renaming to a .ics then opening it <strong>does</strong> display the attached file correctly. This makes me think that there is something wrong with the way I'm sending the message, instead of the iCalendar markup.</p>
  <p>Any ideas what is wrong?</p>