Skip to content

Working with attachments

Rian Stockbower edited this page Apr 7, 2018 · 4 revisions

RFC 5545 allows for attachments on several calendar components.

RFC 5445 ical.net
VALARM Alarm
VEVENT CalendarEvent
VTODO Todo
VJOURNAL Journal

Attachments come in two forms:

  • Uris pointing to some network-accessible resource
  • Base64-encoded strings that can represent anything

Uri attachment

ical.net can serialize any URI that System.Uri can understand: HTTP, email addresses, LDAP URLs, local filesystem paths, UNC paths, etc.

var attachment = new Attachment(new Uri("ldap://example.com:3333/o=eExample Industries,c=3DUS??(cn=3DBJohn Smith)"));
var calendar = new Calendar();
var vEvent = new CalendarEvent
{
    Start = new CalDateTime(DateTime.Parse("2016-07-23T07:00:00-04:00")),
    End = new CalDateTime(DateTime.Parse("2016-07-23T08:00:00-04:00")),
};

vEvent.Attachments = new List<Attachment> { attachment };
calendar.Events.Add(vEvent);

And we can get the URI back:

var uri = calendar
    .Events
    .First()
    .Attachments
    .Select(a => a.Uri)
    .Single();

Base64-encoded attachment

Base64-encoded attachments can represent anything: numbers, strings, serialized objects, etc. If you can turn it into a byte array (byte[]), you can create an attachment from it.

This example shows how to attach a JSON-serialized representation of an object to a CalendarEvent.

public class SomeObject
{
    public List<string> TheList { get; }
    public int TheNumber { get; }
    public ISet<string> TheSet { get; }

    public SomeObject(List<string> theList, int theNumber, IEnumerable<string> theSet)
    {
        TheList = theList;
        TheNumber = theNumber;
        TheSet = new HashSet<string>(theSet);
    }
}

Suppose you serialize an instance to JSON:

var collection = new List<string>
{
    "Foo", "Bar", "Baz", "Foo", "Bar", "Baz", "Foo", "Bar", "Baz",
    "Foo", "Bar", "Baz", "Foo", "Bar", "Baz", "Foo", "Bar", "Baz",
};

var someObject = new SomeObject(thisList: collection, theNumber: 42, theSet: collection);
var json = JsonConvert.SerializeObject(someObject);  //JSON.net

And you want to attach it to an instance of a CalendarEvent object:

var asBytes = Encoding.UTF8.GetBytes(json);
var binaryAttachment = new Attachment(asBytes);

var calendar = new Calendar();
var vEvent = new CalendarEvent
{
    Start = new CalDateTime(DateTime.Parse("2016-07-23T07:00:00-04:00")),
    End = new CalDateTime(DateTime.Parse("2016-07-23T08:00:00-04:00")),
};
vEvent.Attachments = new List<Attachment> { attachment };
calendar.Events.Add(vEvent);

You can then rehydrate an instance of SomeObject:

var newSomeObj = calendar
    .Events
    .First()
    .Attachments
    .Select(a => Encoding.UTF8.GetString(a.Data))
    .Select(json => JsonConvert.DeserializeObject<SomeObject>(json))
    .Single();