Accessing Hotmail using C#

HotmailClient

Now for implementing a class that provides access to Hotmail. The following example will show how to connect to Hotmail using the proxy, get the msgfolderroot and request some information about mailboxes. The msgfolderroot can be queried for information such as mailbox names, message count and unread count. This will allow clients to determine how many messages are new, without having to download all the messages. (Which would be a stupid method to implement such behavior.)

Using this example and the webpage provided at the top of this document, it will be easy to implement the rest of an email client (it was for me!).

First let's begin again with the class framework:

public class HotmailClient
{
    private HotmailProxy hHttp = null;
   
    public HotmailClient()
    {
    }
}

Connect()

Now for the only public method, Connect(). This method will connect to Hotmail using HTTP authentication, it will parse the response to obtain the Url of the msgfolderroot. Next this Url will be used to determine some mailbox information.

First of all the proxy class en credentials needed for authentication are build:

    public void Connect(string username, string password)
    {
        hHttp = new HotmailHttp();
        NetworkCredential credentials =
            new NetworkCredential(username,password,null);

Pffew, that was hard, one complete line of code. Easy enough as you can see! The next job will be to build the XML query for the msgfolderroot. (XmlHttp will return all kinds of nonsense about the inbox, advertisements and others while as you can see only the msgfolderroot is requested).

        string query = "<?xml version='1.0'?>" +
            "<D:propfind xmlns:D='DAV:' " +
            "xmlns:h='http://schemas.microsoft.com/hotmail/' " +
            "xmlns:hm='urn:schemas:httpmail:'>" +
            "<D:prop>" +
                <hm:msgfolderroot/>" +
            "</D:prop>" +
            "</D:propfind>";

The query and the credentials can be used to get a response from the Hotmail gateway located at http://services.msn.com/svcs/hotmail/httpmail.asp. This will cause several redirections and cause the HTTP authentication to take place. All can be done with just a single line of code.

        try
        {
            string hotmailEntryPoint =
                "http://services.msn.com/svcs/hotmail/httpmail.asp;
            string response = hHttp.SendRequest(query,
                new Uri(hotmailEntryPoint),credentials);
            // Verify response
            if (response == null || response.Trim().Length == 0)
                throw new Exception();

The Hotmail server will respond with the Url of the msgfolderroot. This Url is placed in the XML based response, so it can be found using Xpath. Another method has been build to do just that.

            // Parse the response, further verifying it.
            Uri folderRootUri = ParseConnectResponse(response);

With the now obtained Url, information about all the mailboxes on the server can be retrieved.

            // Obtain available folders using folderRootUrl
            RetrieveMailboxes(folderRootUri);
        }
        catch(Exception e)
        {
            // Something went wrong.
            throw new MailException("Exception occured while " +
                "connecting to remote host.",e);
        }

This completes our first method. As you can see it calls two other methods which we will now construct, these two contain the interesting parts, parsing the response! But first an important helper method needs to be build, without it all XPath queries fail.

CreateNamespaceManager (XmlNameTable table)

To obtain the Url of the folder root we will use XPath. The problem lies in the fact that XPath will not return results for nodes that are declared in a namespace. It is able to do so, but information about namespaces need to be stated with the XPath query. This can be done by constructing an XmlNamespaceManager that knows about the namespaces in the Hotmail responses. As these namespaces appear to be really constant, a special method can be build to construct the necessary object.

private XmlNamespaceManager CreateNamespaceManager(
        XmlNameTable table)
{
    XmlNamespaceManager m = new XmlNamespaceManager(table);
    m.AddNamespace("hm","urn:schemas:httpmail:");
    m.AddNamespace("D","DAV:");
    m.AddNamespace("m","urn:schemas:mailheader:");
    m.AddNamespace("c","urn:schemas:contacts:");
    m.AddNamespace("h","http://schemas.microsoft.com/hotmail/");
    return m;
}

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“XML is like violence - if it's not working for you, you're not using enough of it.”