Library tutorials & articles

Accessing Hotmail using C#

HotmailClient contd.

ParseConnectResponse(string response)

To parse the response there are a two things that need to be done; place the returned response in an XmlDocument and parse the document using XPath to obtain the Url of the msgfolderroot.

private Uri ParseConnectResponse(string response)
{
    try
    {
        // Load response into XmlDocument
        XmlDocument dom = new XmlDocument();
        dom.LoadXml(response);
        // Query XmlDocument for msgfolderroot node.
        string xpath = "//hm:msgfolderroot";
        XmlNamespaceManager context =
            CreateNamespaceManager(dom.NameTable);
        XmlNode folderRoot = dom.SelectSingleNode(xpath,context);
        // Verify node
        if (folderRoot == null)
            throw new Exception("Node '" + xpath +
                "' not found.");
        // Get node text and verify,
        string folderRootUrl = folderRoot.InnerText;
        if ((folderRootUrl == null) ||
            (folderRootUrl.Trim().Length == 0))
            throw new MailException("No url found in node '" +
                xpath + "'.");
        try
        {
            // Return the uri, this may result in a
            // UriFormatException
            return new Uri(folderRootUrl);
        }
        catch
        {
            throw new MailException("Url found in node '" +
                xpath + "' is invalid:" + folderRootUrl);
        }
    }
    catch(Exception e)
    {
        // Something went wrong.
        throw new MailException("Error occured while parsing " +
            "connect response.",e);
    }
}

The way this method works is pretty basic now. The correct query to make can be determined using the webpage stated in the introduction, it's also possible to use a network analyzer for this purpose. Probably you will need to use both. To parse the response, the XmlNamespaceManager is build, and XPath is used.

RetrieveMailboxes(Uri folderRootUrl)

The last method in this example will retrieve information about all mailboxes on the server. Basically it does the same thing as the first two methods combined, so you should already be able to build it yourself. The method is shown here for completion sake. It will build a query and send it to the Url of the msgfolderroot now determined.

private void RetrieveMailboxes(Uri folderRootUrl)
{
    try
    {
        // Build the needed query
        string query =    "<?xml version='1.0'?>" +
            "<D:propfind xmlns:D='DAV:' " +
            "xmlns:hm='urn:schemas:httpmail:'>" +
            "<D:prop>" +
            "<D:displayname/>" +
            "<hm:special/>" +
            "<hm:unreadcount/>" +
            "<D:visiblecount/>" +
            "</D:prop>" +
            "</D:propfind>";
        // Get a response from server No Credentials are used!
        string response = hHttp.SendRequest(query,folderRootUrl);
        // Verify response
        if (response == null || response.Trim().Length == 0)
            throw new ApplicationException
                ("No response received from host.");   
        // Load response into XmlDocument
        XmlDocument dom = new XmlDocument();
        dom.LoadXml(response);
        // Query XmlDocument for all mailboxes using XPath
        string xpath = "//D:response";
        XmlNamespaceManager context =
            CreateNamespaceManager(dom.NameTable);
        XmlNodeList mailBoxNodes =
            dom.SelectNodes(xpath,context);
        // Parse each node found
        foreach(XmlNode mailBoxNode in mailBoxNodes)
        {       
            try
            {
                // Direct mapping using XPath, should not
                // result in any errors
                // as long as Hotmail keeps it protocol
                // the same.
                string type = mailBoxNode.SelectSingleNode("descendant::hm:special",context).InnerText;
                string nameUrl = mailBoxNode.SelectSingleNode("descendant::D:href",context).InnerText;
                int visibleCount = Int32.Parse(mailBoxNode.
                    SelectSingleNode("descendant::D:visiblecount",context).InnerText);
                int unreadCount = Int32.Parse(mailBoxNode.
                    SelectSingleNode("descendant::hm:unreadcount",context).InnerText);
                Console.WriteLine("MailBox found: " +
                    type + "\r\n" + "\turl: " +
                    nameUrl + "\r\n" + "\tVisible: " +
                    visibleCount + "\r\n" + "\tUnread: " +
                    unreadCount + "\r\n");
            }
            catch(Exception e)
            {
                Console.WriteLine("Exception occured while obtaining mailbox info: " + e.Message);
            }
        }
    }
    catch(Exception e)
    {
        // Something went wrong.
        throw new ApplicationException("Error occured " +
            "while retrieving available mailboxes.",e);
    }
}

Conclusion

As you can see accessing Hotmail from C# can be as easy as any other type of mail server. The code works without any strange loops or use of classes that function only partly. With this code it should be easy to build your own email client that is able to access Hotmail with the same type of interface as you would build for IMAP or POP. Happy coding!

Comments

  1. 13 Dec 2004 at 11:48
    Which one is the wannabee? You or Code Project author of the same class.....

    Thx!
    Tidoy
  2. 06 Dec 2004 at 07:37

    Hi,


    I tried running this code as it would have been nice to develop my own hotmail client, however on running it does say Error 402 Payment Requred, on some research it does look like to you have to be a paying member of the hotmail service ($19 annually i think) to be able to use these set of objects.


    Shame.

  3. 01 Jan 1999 at 00:00

    This thread is for discussions of Accessing Hotmail using C#.

Leave a comment

Sign in or Join us (it's free).

Wouter van Vugt

Related podcasts

  • Object-Oriented Programming in Ruby

    In this episode, I talk with Scott Bellware about object-oriented programming in Ruby, and Ruby's object model. This is taken from a private conversation, and the audio quality suffers at times. Much thanks to Scott for allowing this to be released.This episode of the Alt.NET Podcast is bro...

Want to stay in touch with what's going on? Follow us on twitter!