How do I create an HTML-formatted ICS message body using ical.net?

Barax picture Barax · Dec 23, 2016 · Viewed 17.6k times · Source

I need send reminders to users of a web application.

To do this I use iCal.Net from nuget packages. Following instructions about the usage I'm able to send an email with an attachment containing the ics file.

Is it possible to format the event description as html and make it working on both Outlook office client and Chrome calendar?

On these clients I see plain text representation with all the html tags. I tested also on Windows 10 calendar where the event description is correctly displayed as html. Do I have to set something more?

This is my calendar string generation

var now = DateTime.Now;
var later = scadenza.Value;

var e = new Event
{
    DtStart = new CalDateTime(later),
    DtEnd = new CalDateTime(later),
    Description = mailText,
    IsAllDay = true,
    Created = new CalDateTime(DateTime.Now),
    Summary = $"Reminder for XYZ",

};

var attendee = new Attendee
{
    CommonName = "…..",
    Rsvp = true,
    Value = new Uri("mailto:" + ConfigurationManager.AppSettings["ReminderReceiver"])
};
e.    Attendees = new List<IAttendee> { attendee };

var calendar = new Calendar();
calendar.Events.Add(e);

var serializer = new CalendarSerializer(new SerializationContext());
var icalString = serializer.SerializeToString(calendar);

Answer

rianjs picture rianjs · Dec 23, 2016

HTML formatting isn't part of the icalendar spec, so it's up to applications to add support for this via the non-standard property fields, which are designated with an X- prefix. (Further reading on non-standard properties if you're interested.)

Google calendar

It doesn't look like Google calendar has any support for HTML-formatted events, so I think you're out of luck there.

Outlook

Outlook uses a number of these X- fields for various things; for HTML-formatted descriptions, it uses X-ALT-DESC and specifies FMTTYPE=text/html like this:

X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//E
    N">\n<HTML>\n<HEAD>\n<META NAME="Generator" CONTENT="MS Exchange Server ve
    rsion rmj.rmm.rup.rpr">\n<TITLE></TITLE>\n</HEAD>\n<BODY>\n<!-- Converted 
    from text/rtf format -->\n\n<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Cali
    bri">This is some</FONT></SPAN><SPAN LANG="en-us"><B> <FONT FACE="Calibri"
    >HTML</FONT></B></SPAN><SPAN LANG="en-us"><FONT FACE="Calibri"></FONT></SP
    AN><SPAN LANG="en-us"><U> <FONT FACE="Calibri">formatted</FONT></U></SPAN>
    <SPAN LANG="en-us"><FONT FACE="Calibri"></FONT></SPAN><SPAN LANG="en-us"><
    I> <FONT FACE="Calibri">text</FONT></I></SPAN><SPAN LANG="en-us"><FONT FAC
    E="Calibri">.</FONT></SPAN><SPAN LANG="en-us"></SPAN></P>\n\n</BODY>\n</HT
    ML>

You may be able to get away with much simpler HTML, you'll have to test to see what Outlook supports/allows. The HTML block above was generated using Outlook 2013. I have successfully used that block and run it through a serialization round-trip with ical.net, and Outlook opens it without any fuss.

ical.net

Unfortunately you can't quite do this in ical.net due a bug with CalendarProperty serialization, but the workaround is just one line.

const string formatted = //the text block from above starting with FMTTYPE=text/html:

var start = DateTime.Now;
var end = start.AddHours(1);
var @event = new Event
{
    Start = new CalDateTime(start),
    End = new CalDateTime(end),
    Description = "This is a description",
};
var property = new CalendarProperty("X-ALT-DESC", formatted);
@event.AddProperty(property);
var calendar = new Calendar();
calendar.Events.Add(@event);

var serialized = new CalendarSerializer().SerializeToString(calendar);

//Workaround for the bug:
serialized = serialized.Replace("X-ALT-DESC:FMTTYPE=text/html", "X-ALT-DESC;FMTTYPE=text/html");

This will produce HTML-formatted Outlook calendar events.

(When I fix the bug, I'll update this answer to remove the string.Replace call.)