Académique Documents
Professionnel Documents
Culture Documents
Definitions
WebDAV stands for Web-based Distributed Authoring and Versioning. It is a set of extensions to the HTTP protocol which allows users collaboratively to edit and manage files or datastores on remote web servers. OWA stands for Outlook Web Access.
Overview
I have broken the process into two articles, this first one being about extracting the data into a usable format. I will follow this up with how to use the data in a team calendar web page. This article demonstrates how to extract calendar events from Microsoft Exchange using Outlook Web Access (OWA) into a .NET Dataset. The following steps are taken to retrieve the data: 1. 2. 3. Build WebDav Query. Parse returned DOM and build Dataset. Use dataset in any way you see fit.
Requirements
MS Exchange 2003 with Web Mail installed. Please Note: Authentication method must be known. A user setup with permissions to review the personal calendars in MS Exchange. The actual mail box names for the members to be displayed (this is very important, often the NT logon name). Visual Studio 2003 and working knowledge of XML and SQL. And finally patience and a strong will to live.
Page 1
return to index
Process Flow
Page 2
return to index
Page 3
return to index
When dealing with forms based authentication, a session cookie must be received from the exchange server and passed with every call made to the server. I have attached the following method to retrieve the authentication cookies.
public CookieCollection ExchangeFormBasedAuthenticationCookies (string uri1,NetworkCredential credential) { // Get the server portion of the requested uri and append the authentication dll from Exchange string server = uri.Substring(0, uri.IndexOf(/, 8)) + /exchweb/bin/auth/owaauth.dll; HttpWebRequest request = (System.Net.HttpWebRequest)HttpWebRequest.Create(server); request.Method = POST; //Create cookie container to retrieve return cookiecollection request.CookieContainer = new CookieContainer(); request.ContentType = application/x-www-form-urlencoded; byte[] body = Encoding.UTF8.GetBytes(string.Format(destination={0}&username={1}\\{2}&password={3},server + /exchange/ + credential.UserName +/Calendar, credential.Domain, credential.UserName, credential.Password)); request.ContentLength = body.Length; Stream stream = request.GetRequestStream(); stream.Write(body, 0, body.Length); stream.Close(); // Get the response httpWebResponse response = (HttpWebResponse) request.GetResponse(); // Check if the login was successful if (response.Cookies.Count < 2) throw new Exception(Login failed!!); //Return Cookie collection return response.Cookies; }
1.
2.
Please Note: This will not work on a Forms Authenticated Exchange server: you will get an unintuitive response of Login Timeout. When using forms authentication replace point 2 with the following.
//Create Cookie Collection container Request.CookieContainer = new CookieContainer(); //Call Exchange Authentication DLL and return Authentication Cookies (There must be at least 2 cookies or authentication failed.) CookieCollection cookiecollection = ExchangeFormBasedAuthenticationCookies(serverPath,new System.Net.NetworkCredential(strUserName, strPassword,strDomain)); //Assign Authentiacation Cookie to Every call made to the Exchange server Request.CookieContainer.Add(cookiecollection);
Page 4
return to index
3.
4.
5.
6.
// Get a reference to the request stream. System.IO.Stream RequestStream = Request.GetRequestStream();
7.
// Write the SQL query to the request stream. RequestStream.Write(bytes, 0, bytes.Length);
8.
// Close the Stream object to release the connection // for further use. RequestStream.Close();
9.
Return DataTable
In the example we build a data table on the fly to return the data.
Table structure
Field name Entry ID Subject Location Busy AllDayEvent Sensitivity InstanceType Href StartTime EndTime Data Type Description String String String String Boolean String String String DateTime DateTime Unique identifier assigned be MS exchange server for the calendar event. Subject line of the calendar event. Location of the calendar event. OOF, Busy, Free, Tentative Status for the calendar event. Mark the event as an ALL Day Event. Indicates Level of Sensitivity (Private indicates private check box was ticked, blank makes it a public event) Instance type. This is the URL to the item on the on the IIS server. Start date for the calendar event. End date for the calendar event.
Page 5
return to index
We then loop through all the XMLNodes and insert each Item into the DataTable.
#region Build return dataset. //Build Return Table. DataTable calendarEventsTable = BuildCalendarTable(tableName); for(int i=0; i<SubjectNodeList.Count; i++) { DataRow calendarEventRow = calendarEventsTable.NewRow(); calendarEventRow[EntryID] = EntryIDNodeList[i].InnerText; calendarEventRow[Subject] = SubjectNodeList[i].InnerText; calendarEventRow[Notes] = NotesNodeList[i].InnerText.ToString(); calendarEventRow[Location] = LocationNodeList[i].InnerText; calendarEventRow[Busy] = BusyStatusNodeList[i].InnerText; if (AlldayEventNodeList[i].InnerText == 1) calendarEventRow[AllDayEvent] = true; else calendarEventRow[AllDayEvent] = false; calendarEventRow[Sensitivity] calendarEventRow[InstanceType] calendarEventRow[href] = SensitivityNodeList[i].InnerText; = InstanceTypeNodeList[i].InnerText; = hrefNodeList[i].InnerText;
Page 6
return to index
The resulting DataSet can be consumed in any .NET application using DataBinding. I hope this article gives you a better idea on how to create a team calendar without much effort or time. Leslie Drewery GG (general gopher) is one of the developers for CompuFile Limited. He develops in Delphi and C# covering Win32 through to ASP.net and recently DirectShow using DirectX and not much of an author. [Im not complaining! Ed] He also has a keen interest in PC based Digital TV systems using .net. He can be reached via his website http://www.firedtv.com or email leslie@firectv.com [Thanks to Brian Long for tech editing and commenting on this article. Any remaining anomalies are mine. Ed]
About dzTemplates
dzTemplates has grown out of the article linked above. It is a set of type safe containers that can be easily used to store whatever data you want it to store.
Available containers
The following containers are available:
List templates are the most generic containers. They come in two flavours: One that stores anything
that can be typecasted into a pointer or an interface and one that assumes the items are descendants of TObject and "owns" them (that is, it will free them in its destructor). There is also an interface declaration for this kind of container (dzListInterfaceTemplate).
dzListTemplate / dzObjectListTemplate is the most generic container it stores its items in the
order they are added.
dzIntegerSortedListTemplate / dzIntegerSortedObjectListTemplate is a specialized descendant of dzSortedListTemplate which assumes that its items are sorted by an integer value.
dzStackTemplate / dzObjectStackTemplate are both stacks (LIFO = last in first out), again one for
storing anything that can be typecasted to a pointer or interface and one for storing TObject descendants.
dzQueueTemplate is a queue (FIFO = first in first out) for storing anything that can be typecasted to a
pointer or interface. There currently is not dzObjectQueueTemplate but I will add one shortly.
dzHashTemplate is a hash or associative array for storing items and accessing them via an associated
string.
Page 7
return to index