<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>David Szabo's [MSFT] blog : OWA</title><link>http://blogs.msdn.com/dszabo/archive/tags/OWA/default.aspx</link><description>Tags: OWA</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Exchange 2003 meeting request submission, update and cancellation from server-side applications</title><link>http://blogs.msdn.com/dszabo/archive/2006/11/09/exchange-2003-meeting-request-submission-update-cancellation-and-free-busy-from-server-side-application.aspx</link><pubDate>Thu, 09 Nov 2006 09:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1039519</guid><dc:creator>dszabo</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/dszabo/comments/1039519.aspx</comments><wfw:commentRss>http://blogs.msdn.com/dszabo/commentrss.aspx?PostID=1039519</wfw:commentRss><description>&lt;P&gt;I recently had a project where part of the functionality was to make meeting room booking functionality&amp;nbsp;against Exchange Server 2003 (I re-invented OWA :) - no, it was just part of the application, integrated with other functionalities), and also to cancel or update the request and do free/busy lookup. It was an ASP.net application, so the application was running in an IIS worker process, meaning that I had to use server-side APIs to do the job. Otherwise, a popup message could block the server process, making my web application unresponsible. The APIs available for server-side applications are&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Extended MAPI (note: it's not supported from .net, so it's not a real choice)&lt;/LI&gt;
&lt;LI&gt;CDOEX&lt;/LI&gt;
&lt;LI&gt;CDOSYS&lt;/LI&gt;
&lt;LI&gt;WebDav&lt;/LI&gt;
&lt;LI&gt;ExOleDb&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;As you might now, I was working as a support engineer at the Exchange Development team at Microsoft GTSC-PSS, so if I’m not going to use an official documented API to do the stuff, who does it then? So I *HAVE TO* do it in a right way.&lt;/P&gt;
&lt;P&gt;Creating, cancelling and updating a meeting request is not just a raw operation (like changing a property or copying an item), so the APIs above were shrinked down to the ones containing the business logic for these operations. This is a shorter list:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;CDOEX&lt;/LI&gt;
&lt;LI&gt;WebDav&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;… partially: CDOEX is OK, it has all the business logic I need, but the problem is that it can be used only on the Exchange Server, locally (otherwise, part of its functionality doesn't work). Of course, my app is running on a different box. As an alternative choice, I could have designed my application to publish the CDOEX functionality on the Exchange Server as a&amp;nbsp;set of webservice methods, but I couldn't do that, due to (obvious) security and performance reasons at the Customer.&lt;/P&gt;
&lt;P&gt;So, WebDav remains. Hmmm … not a broad list of choices! :)&amp;nbsp; Let's check the documentation around WebDav:&amp;nbsp;the kb article at &lt;A href="http://support.microsoft.com/?id=308373"&gt;http://support.microsoft.com/?id=308373&lt;/A&gt;&amp;nbsp;tells you&amp;nbsp;how to send a meeting request with WebDav, while &lt;A href="http://support.microsoft.com/?id=920134" mce_href="http://support.microsoft.com/?id=920134"&gt;http://support.microsoft.com/?id=920134&lt;/A&gt;&amp;nbsp;tells that nothing else is supported than&amp;nbsp;a few operations listed there (of course,&amp;nbsp;the operations needed for me are not on the list).&amp;nbsp;So, WebDav is also not a good choice, as even if it&amp;nbsp;*COULD* be used to create the meeting request, then later, after you sent the request, you are alone in the dark again, as it’s *SURELY* not supported to cancel or update it. The reason could be that just part of the fields needed for these operations are documented/created in the WebDav calendar schema. So, I’m in a big trouble now: there’s no way to deliver my funcionality with documented APIs. Of course, Exchange 2007 brings the nice and shiny webservices out of the box, but I can’t wait for it, or even if I could, my Customer is not going to upgrade for another 1-2 years. So, I’m in a real trouble.&lt;/P&gt;
&lt;P&gt;Then, OWA came into my mind. Every functionality that OWA has, can be called by HTTP requests (that's the way Http works :). Of course, the way OWA handles meeting requests is OK. The only question is that if it’s supported (will it change after the next SP?) or not. Unfortunately, it's also not supported, but it's partially documented. So, this seems to be the&amp;nbsp;best (and only) choice remained. You can find the OWA customization docu at &lt;A href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=6532E454-073E-4974-A800-1490A7CB358F"&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=6532E454-073E-4974-A800-1490A7CB358F&lt;/A&gt;, it's a&amp;nbsp;nice documentation, worth a look!&amp;nbsp;So, I started reverse engineering my scenarios by using NetMon 2.0 and wrote some nice helper functions. Pasted here&amp;nbsp;the simplified copies&amp;nbsp;FYI. Here they are:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Cancelling a meeting request with an OWA command:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This sample shows you how to cancel a meeting that you organized with multiple attendees. It's just a sample, it's not complete, for example, the folder "Calendar" is hard coded while it could be more smart by reading up the Calendar folder's name from the mailbox root. Anyways, here we go:&lt;/P&gt;&lt;PRE&gt;&lt;P mce_keep="true"&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Cancels a meeting request&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;/// &amp;lt;param name="mainMeetingItemName"&amp;gt;Meeting item name in the user's calendar&amp;lt;/param&amp;gt;&lt;BR&gt;public static void CancelMeetingRequest(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string mainMeetingItemName, string exchSvrName, string mailboxName)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NetworkCredential networkCredential = null;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Set the OWA server's name, the mailbox name and the user's OWA calendar Url&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string owaCalendarUrl = string.Format("http://{0}/exchange/{1}/calendar",&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exchSvrName, mailboxName);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Make sure the slash at the end&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; owaCalendarUrl = MakeSureSlashAtTheEnd(owaCalendarUrl);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the request string&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string webRequest = string.Format("{0}{1}?Cmd=getcancel",&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; owaCalendarUrl, mainMeetingItemName);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the request object&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(webRequest);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Set the credentials based on the configuration settings&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; networkCredential = CredentialCache.DefaultNetworkCredentials;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Credentials = networkCredential;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Set up the headers&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, " +&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; application/msword, */*";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Headers.Add("Accept-Language", "hu");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Headers.Add("Accept-Encoding", "gzip, deflate");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.UserAgent = &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Mozilla/4 0 (compatible; MSIE 6 0; Windows NT 5 1; SV1; " +&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "NET CLR 1 0 3705;&amp;nbsp; NET CLR 1 1 4322;&amp;nbsp; NET CLR 2 0 50727)";&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Send the request and get the response stream&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpWebResponse owaResponse = &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (HttpWebResponse)request.GetResponse();&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Retrieve and form the location of the moved Cancel message.  &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; This message is created by OWA for sending it to the meeting attandees&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string cancelMsgLocation = "http://" + exchSvrName + &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; owaResponse.ResponseUri.AbsolutePath;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Build the mail submission URI of the current user for sending &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // the message&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string submissionUri = "http://" + exchSvrName + "/exchange/" +&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mailboxName + "/##DavMailSubmissionURI##/";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Move the draft message to the submission Uri&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MoveItemWithWebDav(cancelMsgLocation, submissionUri, networkCredential);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Delete the meeting from the calendar&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DeleteItemWithWebDav(owaCalendarUrl + mainMeetingItemName, &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; networkCredential);&lt;BR&gt;}&lt;BR&gt;&lt;/P&gt;
&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;The&amp;nbsp;point&amp;nbsp;is to do a ?Cmd=GetCancel call on the meeting item, retrieve the Url OWA gives back to you in the webresponse (that will be the cancellation item's Url that OWA pre-created for you) and send that item out.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Updating a meeting request with OWA&amp;nbsp;commands&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;This one is a piece of cake! You just have to do the neccessary changes on the meeting item in the organizer's calendar - probably by updating the recipients (to: field -&amp;gt; required attendees, cc: field -&amp;gt; optional attendees, bcc: field -&amp;gt; resources), update the start and end date/time, location&amp;nbsp;of the appointment item if neccessary - as when you create a meeting request with WebDav, then run the following function to ask OWA to send an update to all recipients. Even if you empty the attendees fields (to:, cc:, bcc:), OWA will manage the attendees receive az update request containing the changes:&lt;/P&gt;&lt;PRE&gt;&lt;P mce_keep="true"&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Sends an update to the attendees of a meeting request&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;/// &amp;lt;param name="booking"&amp;gt;A booking instance that has changed&amp;lt;/param&amp;gt;&lt;BR&gt;/// &amp;lt;param name="owaMailboxUrl"&amp;gt;Url of the user's mailbox&amp;lt;/param&amp;gt;&lt;BR&gt;/// &amp;lt;param name="calendarFolderName"&amp;gt;The user's calendar folder name&amp;lt;/param&amp;gt;&lt;BR&gt;public static void UpdateMeetingRecipients(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Data.Booking booking, string owaMailboxUrl, string calendarFolderName)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NetworkCredential networkCredential = null;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Make sure the slash at the end&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; owaMailboxUrl = MakeSureSlashAtTheEnd(owaCalendarUrl);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; calendarFolderName = MakeSureSlashAtTheEnd(calendarFolderName);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Set up the calendar Url&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; owaCalendarUrl = owaMailboxUrl + calendarFolderName&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Collect the meeting item's Url&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string meetingItemUrl = owaCalendarUrl + booking.AppointmentItemName;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the request object&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; meetingItemUrl);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Set the method and content type&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Method = "POST";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.ContentType = "application/x-www-UTF8-encoded";&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Set the network credentials&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; networkCredential = CredentialCache.DefaultNetworkCredentials;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Credentials = networkCredential;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Set up the headers&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, " +&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "application/msword, */*";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Headers.Add("Accept-Language", "hu");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Headers.Add("Accept-Encoding", "gzip, deflate");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.UserAgent = "Mozilla/4 0 (compatible; MSIE 6 0; Windows NT 5 1; " +&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SV1; NET CLR 1 0 3705;&amp;nbsp; NET CLR 1 1 4322;&amp;nbsp; NET CLR 2 0 50727)";&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Write to the request stream&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stream requestStream = request.GetRequestStream();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; StreamWriter requestBodyWriter = new StreamWriter(requestStream);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write("Cmd=sendappt\n");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write("Required=\n");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write("Optional=\n");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write("Resource=\n");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write("FormType=appointment\n");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write(string.Format("MsgID=/{0}{1}\n", &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; calendarFolderName, booking.AppointmentItemName));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write(&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("urn:schemas:httpmail:subject={0}\n", &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Changed: " + booking.Subject));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write(&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("urn:schemas:httpmail:htmldescription={0}\n",&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "This is an updated meeting request));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write(&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("urn:schemas:calendar:dtstart={0}\n", &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConvertDateToOwaFormat(booking.Start)));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write(&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("urn:schemas:calendar:dtend={0}\n", &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConvertDateToOwaFormat(booking.End)));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write(&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("urn:schemas:calendar:location={0}\n", &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; booking.MeetingRoom.Name));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write(&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format("CALENDAR:UID=/{0}{1}\n", &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; calendarFolderName, booking.AppointmentItemName));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write(&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "urn:schemas:calendar:responserequested=1\n");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Write(&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string.Format(&lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "http://schemas.microsoft.com/exchange/subject-utf8=%7B0%7D/n", &lt;/P&gt;&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; booking.Subject));&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Flush the stream&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Flush();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestBodyWriter.Close();&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Send the request&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpWebResponse owaResponse = (HttpWebResponse)request.GetResponse();&lt;BR&gt;}&lt;/P&gt;
&lt;/PRE&gt;This is nice, isn't it? :)&amp;nbsp; 
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Creating the meeting request&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;For creating a meeting request, I used the documented way with WebDav, which seems to be also not supported: &lt;A href="http://support.microsoft.com/?id=308373"&gt;http://support.microsoft.com/?id=308373&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Summary&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Don't forget that the examples shown above are unsupported and they may won't work with the next service pack of Exchange Server 2003. If you have a chance, use CDOEX on the Exchange Server by exposing it as a set of webservices. Otherwise, you could use this unsupported thing that I mentioned above, but if there's anything going wrong, you can't go to Microsoft Product Support for help. Feel free to post any questions here, if there's a problem with it.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1039519" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/dszabo/archive/tags/Exchange/default.aspx">Exchange</category><category domain="http://blogs.msdn.com/dszabo/archive/tags/OWA/default.aspx">OWA</category></item></channel></rss>