This sample project shows how to load events (appointments) for Microsoft Exchange Server and display them in an ASP.NET web application using DayPilot ASP.NET event calendar. It supports drag and drop operations for event creating and moving. Changes are stored in the Exchange Server.

Features

  • Accessing Microsoft Exchange Server 2007+ (including hosted Exchange and Office 365)
  • Uses Exchange Web Services Managed API
  • C# and VB.NET source code
  • Includes open-source DayPilot Lite for ASP.NET WebForms
  • Loading appointments
  • Updating appointments
  • Creating appointments
  • Sample Visual Studio 2017 solution available for download

License

  • The source code of this sample project is licensed under Apache License 2.0.
  • DayPilot Lite for ASP.NET WebForms (open-source version) is licensed under Apache License 2.0.

DayPilot Installation

You can install DayPilot Lite for ASP.NET WebForms (open-source version) from NuGet:

Another option is to download the DayPilot package and add a reference to DayPilot.dll.

asp.net-calendar-nuget-daypilot.png

Microsoft EWS Managed API Installation

You can install Microsoft Exchange WebSerices Managed API from NuGet:

Since 2014 Microsoft EWS Managed API is open-source (MIT license). You can download the source code at GitHub.

  • You can use EWS to connect to Microsoft Exchange Server 2007 or later.
  • It works with Office 365 mail accounts as well.

asp.net-calendar-nuget-exchange-web-services.png

Loading Appointments from Exchange Server

asp.net-calendar-exchange-office-365-online.png

The following code loads appointments for the current week from the default calendar of the specified user

C#

// Exchange connection
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
service.Credentials = new WebCredentials("user@yourcompany.com", "password");   // replace with proper username and password
service.Url = new Uri("https://outlook.office365.com/ews/exchange.asmx");   // Office 365 Exchange API URL (replace it with a local server URL if you are using a local Exchange installation)

// this week
DateTime startDate = DayPilot.Utils.Week.FirstDayOfWeek();
DateTime endDate = startDate.AddDays(7);

// load the default calendar
CalendarFolder calendar = CalendarFolder.Bind(Service, WellKnownFolderName.Calendar, new PropertySet());

// load events
CalendarView cView = new CalendarView(startDate, endDate, 50);
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Id);
FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);

VB

Dim svc As New ExchangeService(ExchangeVersion.Exchange2010)
svc.Credentials = New WebCredentials("user@yourcompany.com", "password")
svc.Url = New Uri("https://outlook.office365.com/ews/exchange.asmx")

Dim startDate As Date = DayPilot.Utils.Week.FirstDayOfWeek()
Dim endDate As Date = startDate.AddDays(7)

Dim calendar As CalendarFolder = CalendarFolder.Bind(svc, WellKnownFolderName.Calendar, New PropertySet())

Dim cView As New CalendarView(startDate, endDate, 50)
cView.PropertySet = New PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Id)
Dim appointments As FindItemsResults(Of Appointment) = calendar.FindAppointments(cView)

Displaying Exchange Appointments in DayPilot Event Calendar

asp.net-calendar-exchange-office-365-preview.png

You can assign the appointments variable directly to DayPilotCalendar.DataSource property to load it:

C#

// assign appointments
DayPilotCalendar1.DataSource = appointments;

// map item properties
DayPilotCalendar1.DataStartField = "Start";
DayPilotCalendar1.DataEndField = "End";
DayPilotCalendar1.DataIdField = "Id";
DayPilotCalendar1.DataTextField = "Subject";

// load and display appointments in DayPilot Calendar
DayPilotCalendar1.DataBind();

VB

' assign appointments
DayPilotCalendar1.DataSource = appointments

' map item properties
DayPilotCalendar1.DataStartField = "Start"
DayPilotCalendar1.DataEndField = "End"
DayPilotCalendar1.DataIdField = "Id"
DayPilotCalendar1.DataTextField = "Subject"

' load and display appointments in DayPilot Calendar
DayPilotCalendar1.DataBind()

Loading a Custom Exchange Calendar

asp.net-calendar-exchange-office-365-custom.png

You can also load a custom calendar instead of the default one (WellKnownFolderName.Calendar).

C#

// Exchange connection
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
service.Credentials = new WebCredentials("user@yourcompany.com", "password");   // replace with proper username and password
service.Url = new Uri("https://outlook.office365.com/ews/exchange.asmx");   // Office 365 Exchange API URL (replace it with a local server URL if you are using a local Exchange installation)

// this week
DateTime startDate = DayPilot.Utils.Week.FirstDayOfWeek();
DateTime endDate = startDate.AddDays(7);

// load a calendar by name
string name = "Testing Calendar";
FolderView view = new FolderView(100);
view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
view.PropertySet.Add(FolderSchema.DisplayName);
view.Traversal = FolderTraversal.Deep;
SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.FolderClass, "IPF.Appointment");
FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.Root, sfSearchFilter, view);
CalendarFolder calendar = findFolderResults.Where(f => f.DisplayName == name).Cast<CalendarFolder>().FirstOrDefault();

// load events
CalendarView cView = new CalendarView(startDate, endDate, 50);
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Id);
FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);

VB

Dim svc As New ExchangeService(ExchangeVersion.Exchange2010)
svc.Credentials = New WebCredentials("user@yourcompany.com", "password")
svc.Url = New Uri("https://outlook.office365.com/ews/exchange.asmx")

Dim startDate As Date = DayPilot.Utils.Week.FirstDayOfWeek()
Dim endDate As Date = startDate.AddDays(7)


Dim name As String = "Testing Calendar"
Dim view As New FolderView(100)
view.PropertySet = New PropertySet(BasePropertySet.IdOnly)
view.PropertySet.Add(FolderSchema.DisplayName)
view.Traversal = FolderTraversal.Deep

Dim sfSearchFilter As SearchFilter = New SearchFilter.IsEqualTo(FolderSchema.FolderClass, "IPF.Appointment")

Dim findFolderResults As FindFoldersResults = svc.FindFolders(WellKnownFolderName.Root, sfSearchFilter, view)
Dim calendar As CalendarFolder = findFolderResults.Where(Function(f) f.DisplayName = name).Cast(Of CalendarFolder)().FirstOrDefault()

Dim cView As New CalendarView(startDate, endDate, 50)
cView.PropertySet = New PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Id)
Dim appointments As FindItemsResults(Of Appointment) = calendar.FindAppointments(cView)

Full Calendar Loading Page

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestExchange.Default" %>
<%@ Register Assembly="DayPilot" Namespace="DayPilot.Web.Ui" TagPrefix="DayPilot" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <DayPilot:DayPilotCalendar runat="server" id="DayPilotCalendar1"></DayPilot:DayPilotCalendar>
        </div>
    </form>
</body>
</html>

Default.aspx.cs

using System;
using System.Linq;
using DayPilot.Web.Ui.Enums.Calendar;
using DayPilot.Web.Ui.Events;
using Microsoft.Exchange.WebServices.Data;

namespace TutorialCS
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            LoadAppointments();
        }

        private ExchangeService Service
        {
            get
            {
                ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
                service.Credentials = new WebCredentials("user@yourcompany.com", "password");
                service.Url = new Uri("https://outlook.office365.com/ews/exchange.asmx");
                return service;
            }
        }

        private CalendarFolder FindDefaultCalendarFolder()
        {
            return CalendarFolder.Bind(Service, WellKnownFolderName.Calendar, new PropertySet());
        }


        private CalendarFolder FindNamedCalendarFolder(string name)
        {
            FolderView view = new FolderView(100);
            view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
            view.PropertySet.Add(FolderSchema.DisplayName);
            view.Traversal = FolderTraversal.Deep;

            SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.FolderClass, "IPF.Appointment");

            FindFoldersResults findFolderResults = Service.FindFolders(WellKnownFolderName.Root, sfSearchFilter, view);
            return findFolderResults.Where(f => f.DisplayName == name).Cast<CalendarFolder>().FirstOrDefault();
        }

        private void LoadAppointments()
        {
            DateTime startDate = DayPilot.Utils.Week.FirstDayOfWeek();
            DateTime endDate = startDate.AddDays(7);

            CalendarFolder calendar = FindNamedCalendarFolder("Testing Calendar");  // or FindDefaultCalendarFolder()

            CalendarView cView = new CalendarView(startDate, endDate, 50);
            cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Id);
            FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);

            DayPilotCalendar1.ViewType = ViewTypeEnum.Week;
            DayPilotCalendar1.DataStartField = "Start";
            DayPilotCalendar1.DataEndField = "End";
            DayPilotCalendar1.DataIdField = "Id";
            DayPilotCalendar1.DataTextField = "Subject";

            DayPilotCalendar1.DataSource = appointments;
            DayPilotCalendar1.DataBind();

            DayPilotCalendar1.Update();

        }

    }
}

Default.aspx.vb

Imports System
Imports System.Linq
Imports DayPilot.Web.Ui.Enums.Calendar
Imports DayPilot.Web.Ui.Events
Imports Microsoft.Exchange.WebServices.Data

Namespace TutorialVB
    Partial Public Class [Default]
        Inherits System.Web.UI.Page

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
            LoadAppointments()
        End Sub

        Private ReadOnly Property Service() As ExchangeService
            Get
                Dim svc As New ExchangeService(ExchangeVersion.Exchange2010)
                svc.Credentials = New WebCredentials("user@yourcompany.com", "password")
                svc.Url = New Uri("https://outlook.office365.com/ews/exchange.asmx")
                Return svc
            End Get
        End Property

        Private Function FindDefaultCalendarFolder() As CalendarFolder
            Return CalendarFolder.Bind(Service, WellKnownFolderName.Calendar, New PropertySet())
        End Function


        Private Function FindNamedCalendarFolder(ByVal name As String) As CalendarFolder
            Dim view As New FolderView(100)
            view.PropertySet = New PropertySet(BasePropertySet.IdOnly)
            view.PropertySet.Add(FolderSchema.DisplayName)
            view.Traversal = FolderTraversal.Deep

            Dim sfSearchFilter As SearchFilter = New SearchFilter.IsEqualTo(FolderSchema.FolderClass, "IPF.Appointment")

            Dim findFolderResults As FindFoldersResults = Service.FindFolders(WellKnownFolderName.Root, sfSearchFilter, view)
            Return findFolderResults.Where(Function(f) f.DisplayName = name).Cast(Of CalendarFolder)().FirstOrDefault()
        End Function

        Private Sub LoadAppointments()
            Dim startDate As Date = DayPilot.Utils.Week.FirstDayOfWeek()
            Dim endDate As Date = startDate.AddDays(7)

            Dim calendar As CalendarFolder = FindNamedCalendarFolder("Testing Calendar") ' or FindDefaultCalendarFolder()

            Dim cView As New CalendarView(startDate, endDate, 50)
            cView.PropertySet = New PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Id)
            Dim appointments As FindItemsResults(Of Appointment) = calendar.FindAppointments(cView)

            DayPilotCalendar1.ViewType = ViewTypeEnum.Week
            DayPilotCalendar1.DataStartField = "Start"
            DayPilotCalendar1.DataEndField = "End"
            DayPilotCalendar1.DataIdField = "Id"
            DayPilotCalendar1.DataTextField = "Subject"

            DayPilotCalendar1.DataSource = appointments
            DayPilotCalendar1.DataBind()

            DayPilotCalendar1.Update()

        End Sub

    End Class
End Namespace

Creating New Appointments in Exchange Server using EWS

asp.net-calendar-exchange-office-365-create.png

Now we will let users create a new event using drag and drop.

The new appointment will be stored in our Exchange Server account.

Default.aspx

<DayPilot:DayPilotCalendar runat="server" id="DayPilotCalendar1"
    ...    
    TimeRangeSelectedHandling="CallBack"
    OnTimeRangeSelected="DayPilotCalendar1_OnTimeRangeSelected"
    >                
</DayPilot:DayPilotCalendar>

Default.aspx.cs

// ...

protected void DayPilotCalendar1_OnTimeRangeSelected(object sender, TimeRangeSelectedEventArgs e)
{
    Appointment appointment = new Appointment(Service);

    appointment.Subject = "New Event";
    appointment.Start = e.Start;
    appointment.End = e.End;

    CalendarFolder folder = FindNamedCalendarFolder("Testing Calendar");

    appointment.Save(folder.Id, SendInvitationsMode.SendToNone);

    LoadAppointments();
}

Default.aspx.vb

' ...

Protected Sub DayPilotCalendar1_OnTimeRangeSelected(ByVal sender As Object, ByVal e As TimeRangeSelectedEventArgs)
    Dim appointment As New Appointment(Service)

    appointment.Subject = "New Event"
    appointment.Start = e.Start
    appointment.End = e.End

    Dim folder As CalendarFolder = FindNamedCalendarFolder("Testing Calendar")

    appointment.Save(folder.Id, SendInvitationsMode.SendToNone)

    LoadAppointments()
End Sub

Updating Appointments in Exchange Server using EWS

asp.net-calendar-exchange-office-365-move.png

We will also implement drag and drop event moving and update the event record in the Exchange Server.

Default.aspx

<DayPilot:DayPilotCalendar runat="server" id="DayPilotCalendar1"
    ...
    EventMoveHandling = "CallBack"
    OnEventMove="DayPilotCalendar1_OnEventMove"
    >                
</DayPilot:DayPilotCalendar>

Default.aspx.cs

protected void DayPilotCalendar1_OnEventMove(object sender, EventMoveEventArgs e)
{
    Appointment appointment = Appointment.Bind(Service, new ItemId(e.Id));

    appointment.Start = e.NewStart;
    appointment.End = e.NewEnd;
    appointment.StartTimeZone = TimeZoneInfo.Local;
    appointment.EndTimeZone = TimeZoneInfo.Local;

    appointment.Update(ConflictResolutionMode.AlwaysOverwrite);

    LoadAppointments();
}

Default.aspx.vb

Protected Sub DayPilotCalendar1_OnEventMove(ByVal sender As Object, ByVal e As EventMoveEventArgs)
    Dim appointment As Appointment = Microsoft.Exchange.WebServices.Data.Appointment.Bind(Service, New ItemId(e.Id))

    appointment.Start = e.NewStart
    appointment.End = e.NewEnd
    appointment.StartTimeZone = TimeZoneInfo.Local
    appointment.EndTimeZone = TimeZoneInfo.Local

    appointment.Update(ConflictResolutionMode.AlwaysOverwrite)

    LoadAppointments()
End Sub