Skip to content

Migrating from dday.ical

Rian Stockbower edited this page Nov 24, 2017 · 6 revisions

ical.net has its roots in dday.ical, but has diverged significantly. In some ways, the API is similar, and in some ways, it's different. Adapting your your code shouldn't take more than a few minutes.

Some things were renamed

The table below is not exhaustive; it only represents the common objects and properties that were renamed. I.e. the stuff you probably interact with in your code. There may be cases where something isn't in the table. Chances are, it's a property casing thing (TZID to TzId) or dropping an i prefix (iCalendarCollection to CalendarCollection).

In general, the naming conventions follow Microsoft's Framework Design Guidelines.

dday.ical ical.net (v4) Notes
iCalendarCollection CalendarCollection
IICalendar ICalendar The interface representing the actual calendar
iCalendar Calendar The concrete representation of the calendar, as specified by the ICalendar interface
iCalDateTime CalDateTime
UTC Utc
Local AsSystemLocal Local did not represent "as the local time associated with the time zone entered". It always represented as the local time the system running the code was on, which is misleading, and, in many server contexts, may not be known by the developer ahead of time.
TZID TzId
iCalTimeZone VTimeZone

Calendar.LoadFromUri was removed

The LoadFromUri method was removed from the Calendar object. You will have to implement one yourself. This was done for a variety of reasons, all stemming from the fact that it isn't possible to write a library that interacts with web resources in a reliably cross-platform manner:

  • It's impossible to support the myriad security scenarios that exist on the modern web
  • Using WebClient leaves .NET Core people out in the cold.
  • Using HttpClient means people writing applications pre .NET 4.5 are left out.
  • async-await isn't available before .NET 4.5, and people relying on non-blocking IO shouldn't be limited by the lowest common denominator, especially in busy server contexts.

Here are two implementations that you can use paste into your app that do the same thing as the old LoadFromUri method.

.NET 4.6+ and .NET Core using HttpClient

async version (preferred)

public static async Task<Calendar> LoadFromUriAsync(Uri uri)
{
    using (var client = new HttpClient())  // In a real application, this should be a long-lived object
    using (var response = await client.GetAsync(uri))
    {
        response.EnsureSuccessStatusCode();
        var result = await response.Content.ReadAsStringAsync();
        return Calendar.Load(result);
    }
}

Synchronous (blocking)

public static Calendar LoadFromUri(Uri uri)
{
    using (var client = new HttpClient())   // In a real application, this should be a long-lived object
    using (var response = client.GetAsync(uri).Result)
    {
        response.EnsureSuccessStatusCode();
        var result = response.Content.ReadAsStringAsync().Result;
        return Calendar.Load(result);
    }
}

Hashing and Equality

These tweaks should be largely invisible, however if you had edge cases where Calendar A and Calendar B were the same, but Equals got it wrong, or they didn't produce identical hash codes, these should be fixed. In short, equality usually didn't account for child collections. ical.net does, top to bottom.

What is this guide missing?

If something bit you, and it's not noted here, please send me an email, or create an issue.