<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>Exchange WebDAV</title><link>http://blogs.interknowlogy.com/timmccarthy/category/102.aspx</link><description>Exchange WebDAV</description><dc:language>en-US</dc:language><generator>.Text Version 0.95.2004.111</generator><item><dc:creator>Tim McCarthy</dc:creator><title>Creating tasks in Exchange using WebDAV</title><link>http://blogs.interknowlogy.com/timmccarthy/archive/2006/08/09/3715.aspx</link><pubDate>Wed, 09 Aug 2006 22:11:00 GMT</pubDate><guid>http://blogs.interknowlogy.com/timmccarthy/archive/2006/08/09/3715.aspx</guid><description>&lt;P&gt;I saw &lt;A href="http://www.thebitguru.com/blog/view/21" target=_blank&gt;this posting&lt;/A&gt; on farhan&amp;#8217;s blog about trying to create tasks in Exchange via WebDAV.&lt;/P&gt;
&lt;P&gt;Well, I have found the correct way to do it.&amp;nbsp; My code is split into too many classes to show how to do it in C#, but I will show the XML that needs to be sent across the wire in the WebDAV request to Exchange:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;IMG ALT="Task WebDAV XML" src="/downloads/timmccarthy/images/task.jpg" /&gt;&lt;/P&gt;
&lt;P&gt;I did not put in the other properties, but you can use &lt;A href="http://groups.google.com/group/microsoft.public.exchange2000.development/browse_thread/thread/64a5a05da1a5a49d/a0350e751a5fef86?lnk=st&amp;amp;q=&amp;amp;rnum=1&amp;amp;hl=en#a0350e751a5fef86" target=_blank&gt;this thread&lt;/A&gt; indexed from google groups as a guide.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://blogs.interknowlogy.com/timmccarthy/aggbug/3715.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Tim McCarthy</dc:creator><title>How to programmatically authenticate to Exchange Server 2003 in .NET with forms-based authentication enabled </title><link>http://blogs.interknowlogy.com/timmccarthy/archive/2006/08/05/3659.aspx</link><pubDate>Sat, 05 Aug 2006 21:41:00 GMT</pubDate><guid>http://blogs.interknowlogy.com/timmccarthy/archive/2006/08/05/3659.aspx</guid><description>&lt;p&gt;&lt;font face="Arial"&gt;I ran into this problem and found a few solutions to it, but none of them really worked or were not really well-designed, or very elegant, in my opinion.  There was a &lt;a href="http://www.kbalertz.com/Feedback_891748.aspx" target="_blank"&gt;good Microsoft Knowledge Base article on kbAlertz &lt;/a&gt;about this problem, which greatly helped me with my solution.  Brad Covelle also posted a &lt;a href="http://blogs.sagestone.net/bcovell/archive/2005/12/28/8053.aspx" target="_blank"&gt;solution&lt;/a&gt; to this on his blog as well.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;One thing that I found wrong when I was trying to use these solutions was that the URL that was posted to seemed wrong.  So I went to &lt;a href="http://www.interknowlogy.com/" target="_blank"&gt;our&lt;/a&gt; Exchange OWA login form and did a View Source on it.  I noticed that it was posting to a different URL than what other examples showed, so I changed it to go to http(s)://&lt;my exchange server dns name&gt;/CookieAuth.dll?logon.  This worked me for me so I stuck to it.  I actually put it into a constant, but it might not be a bad idea to put it into some type of configuration (app.config, web.config, database, etc.) as well.&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;What the solution must do is programmatically post to the Exchange 2003 OWA login form handler, grab the cookies issued, and then use those cookies in all subsequent WebDAV requests to Exchange.  I have come up with a class that will grab the cookies, and also cache the cookies, if you would like to keep the class instance in memory and reuse it later for additional WebDAV requests.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;Here is the class:&lt;/font&gt;&lt;/p&gt;&lt;pre&gt;using System;
using System.Net;
using System.IO;
using System.Text;
using System.Collections.Generic;

namespace MIS.EN.WebDav
{
    /// &lt;summary&gt;
    /// Helper class for using Exchange 2003 OWA forms-based authentication with WebDAV.  This class maintains a 
    /// cache of CookieContainer objects, so if the authentication has already been performed,
    /// then the class will grab the CookieContainer from its cache.
    /// &lt;/summary&gt;
    public class FormsBasedAuthentication
    {
        private Dictionary&lt;string, CookieContainer&gt;&lt;string, cookiecontainer&gt; cookieContainerCache;

        public FormsBasedAuthentication()
        {
            this.cookieContainerCache = new Dictionary&lt;string, CookieContainer&gt;&lt;string, cookiecontainer&gt;();
        }

        private static class Constants
        {
            static Constants() { }
            public const string AuthenticationUrl = "{0}://{1}/CookieAuth.dll?logon";
            public const string RequestContentType = "application/x-www-form-urlencoded";
            public const string RequestMethod = "POST";
            public const string PostData = "destination=Z2FexchangeZ2F&amp;flags=0&amp;username={0}\\{1}&amp;password={2}&amp;SubmitCreds=Log On&amp;forcedownlevel=0&amp;trusted=0";
            public const string HttpWebDavExceptionMessage = "There was an HTTP error trying to use forms-based authentication before the WebDAV request was sent.";
            public const string GenericWebDavExceptionMessage = "There was a general error trying to use forms-based authentication before the WebDAV request was sent.";
        }

        /// &lt;summary&gt;
        /// Logs in to Exchange using forms-based authentication, and grabs the necessary cookies to be used 
        /// for a WebDAV request on an Exchange server configured to use OWA forms-based authentication
        /// &lt;/summary&gt;
        /// &lt;param name="host"&gt;The host name of a URI.  This will typically be represented by something like this:  
        /// mail.contoso.com, with contoso being the name of a fictitious company.&lt;/param&gt;
        /// &lt;param name="scheme"&gt;The scheme name of a URI.  This will always typically be https.&lt;/param&gt;
        /// &lt;param name="credentials"&gt;The security account information that will be posted to the OWA login form.&lt;/param&gt;
        public CookieContainer GetOwaCookies(string host, string scheme, NetworkCredential credentials)
        {
            // This will hold the cookies from OWA
            CookieContainer owaCookies;

            // Build the cache key for the cookie container dictionary
            string cacheKey = scheme + host;

            // Check the cache first
            if (this.cookieContainerCache.ContainsKey(cacheKey))
            {
                owaCookies = this.cookieContainerCache[cacheKey];
            }
            else
            {
                try
                {
                    // Get a new cookie container to populate
                    owaCookies = new CookieContainer();

                    // Build the authentication URI
                    Uri serverUri = new Uri(string.Format(Constants.AuthenticationUrl, scheme, host));

                    // Create the request
                    HttpWebRequest request = WebRequest.Create(serverUri) as HttpWebRequest;

                    // Set the headers
                    request.CookieContainer = new CookieContainer();
                    request.ContentType = Constants.RequestContentType;
                    request.Method = Constants.RequestMethod;
                    request.KeepAlive = true;
                    request.AllowAutoRedirect = false;

                    // Prepare the body of the request with the OWA POST data
                    byte[] body = Encoding.UTF8.GetBytes(string.Format(Constants.PostData, credentials.Domain,
                        credentials.UserName, credentials.Password));

                    // Set the content length of the request
                    request.ContentLength = body.Length;

                    // Send the request to the server
                    using (Stream stream = request.GetRequestStream())
                    {
                        stream.Write(body, 0, body.Length);
                    }

                    // Get the response
                    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                    {
                        // Add the OWA cookies from the response to the cookie container
                        foreach (Cookie cookie in response.Cookies)
                        {
                            owaCookies.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain));
                        }
                    }

                    // Add the cookie container to the cache
                    this.cookieContainerCache.Add(cacheKey, owaCookies);
                }
                catch (WebException e)
                {
                    // Re-throw the exception with a wrapper
                    throw new WebDavException(Constants.HttpWebDavExceptionMessage, e);
                }
                catch (Exception e)
                {
                    // Re-throw the exception with a wrapper
                    throw new WebDavException(Constants.GenericWebDavExceptionMessage, e);
                }
            }
            return owaCookies;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt; To use this class, you&amp;#8217;ll also need this class (for the exceptions being thrown):&lt;/p&gt;&lt;pre&gt;using System;
using System.Runtime.Serialization;

namespace MIS.EN.WebDav
{
    public class WebDavException : ApplicationException
    {
        /// &lt;summary&gt;
        /// Default constructor
        /// &lt;/summary&gt;
        public WebDavException() : base()
        {
        }

        /// &lt;summary&gt;
        /// Initializes with a specified error message.
        /// &lt;/summary&gt;
        /// &lt;param name="message"&gt;A message that describes the error.&lt;/param&gt;
        public WebDavException(string message) : base(message)
        {
        }

        /// &lt;summary&gt;
        /// Initializes with a specified error 
        /// message and a reference to the inner exception that is the cause of this exception.
        /// &lt;/summary&gt;
        /// &lt;param name="message"&gt;The error message that explains the reason for the exception.
        /// &lt;/param&gt;
        /// &lt;param name="exception"&gt;The exception that is the cause of the current exception. 
        /// If the innerException parameter is not a null reference, the current exception 
        /// is raised in a catch block that handles the inner exception.
        /// &lt;/param&gt;
        public WebDavException(string message, Exception exception)
            : base(message, exception)
        {
        }

        /// &lt;summary&gt;
        /// Initializes with serialized data.
        /// &lt;/summary&gt;
        /// &lt;param name="info"&gt;The object that holds the serialized object data.&lt;/param&gt;
        /// &lt;param name="context"&gt;The contextual information about the source or destination.
        /// &lt;/param&gt;
        protected WebDavException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }
}
&lt;/pre&gt;&lt;img src ="http://blogs.interknowlogy.com/timmccarthy/aggbug/3659.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>