Exchange is a Microsoft technology that I’ve used everyday for email, but never really delved into as a developer. I’ve been working on some Office 2007 stuff, so I figured I would give it a try.
I was absolutely knocked out by how much you can do as a developer with Exchange Server 2007. There are a number of things, but what really caught my eye was the Web Service API.
I’ve experimented with CDO and MAPI a little bit in the past, but I’ve always struggled with it. It was always a struggle to download the version of CDO/MAPI that matched my server; and even the most trivial task like sending an email seemed really difficult.
But, with Exchange Server 2007, you can access a wide range of its functionality through its web service API. I didn’t find a lot of documentation about the API – a lot of it seems to be a work in progress – but I managed to get some of it working, so I wanted to share what I’ve learned.
First, I downloaded Exchange Server 2007 from http://www.microsoft.com/technet/prodtechnol/exchange/2007/downloads/beta.mspx. The installation was relatively painless. The setup is quite good, there were a few prerequisites that I didn’t have, so I was notified and had a chance to restart the setup.
The exchange web service is located at http://<yourserver>/EWS/Exchange.asmx, so you can literally just add a web reference to that URL and get a proxy class generated for you.
The main proxy class is ExchangeServiceBinding, you can instantiate it just like any other web proxy class.
The exercise I took myself through was fairly straightforward – what I wanted to do was to expand a distribution list to see who belonged to that list. For each person on that list, I want to check their availability. In other words, I want to see if they are available for a 1–hour meeting today.
The first thing to do is to expand out the distribution alias – Exchange Server 2007 has a web method to do exactly this, so it is just a matter of making the call.
You’ll notice something about the Exchange Server 2007 API that you may love, or you may hate. Notice that the ExpandDL takes a single parameter – an instance of ExpandDLType. That type contains members for all of the information that ExpandDL might need as input.
In my experience, there are essentially two main schools of thought about how to define a Web Service API.
One school of thought is to develop web service methods just like they are ‘regular’ methods. For example, if a web service method needs 4 parameters for input, that web service method signature would have 4 parameters. It is pretty intuitive for developers to use a Web Service API like that.
Another school of thought is to develop web service methods as though they were endpoints to which documents were submitted. I was introduced to this approach when I was a developer on the UDDI feature in Windows Server 2003. That is how we defined our web service API. There are pros and cons to this approach. When you take this approach, you typically start designing the web service method from the XSD schema onwards. When you have to worry about interoperability, this isn’t a bad approach at all. When I worked in UDDI, we worked with other companies to be sure that our UDDI implementatio would work with theirs. Whenever we met, we would work on defining just the XML schema. That helped because some companies used Java, some script and we used .NET to implement our version of UDDI. It would have been difficult to talk about programming interfaces since there were so many in play. What is also helpful about this approach is that you can use XSD schema validation to do some basic parameter checking. For example, consider the following XSD type:
Exchange Server 2007 uses this type as a return value of sorts when you make a request to see a user’s oof (out of office) settings. It’s funny to see a relatively colloquial term like OOF make it into the API of a enterprise messaging solution Anyways, the author of this API is using XSD and its ‘minOccurs’ and ‘maxOccurs’ operators to define what is essentially the post-condition the operation to retrieve a user’s oof.
This can be good for both the producer and consumer of the API. For someone who is looking to use this API, the XSD gives them an idea of what to expect as a return value. When you have detailed documentation, this isn’t a big deal, but when you have a new API like with Exchange Server 2007, reading the XSD is critical. For someone who is developing this API, there is validation that is usually done on the outgoing end of the web service. Each outgoing message (i.e. GetUserOofSettingsResponse) is validated against its schema. If it violates something, it is returning something the user is not expecting, so it fails. Essentially, you are checking against the contract you agreed upon with your intended caller.
This approach was really helpful for us in UDDI because our shared UDDI specification was always changing. What we did was put XSD schema validation on the incoming and outgoing ends of our web service. Whenever we got a UDDI message, we validated it against schema before we passed it on to the appropriate method (ASP.NET allows you a hook to do this before it delegates to the appropriate web method). If the incoming message didn’t pass validation, that meant it would give our actual method trouble of some sort. Either the signature didn’t match, or the expected parameters changed. In any case, if the message failed validation, we threw an exception right away. On the outgoing end, we validated each response message we sent against its schema. If something failed validation, that meant whatever we were returning was not what was expected by our caller. Again, we threw an exception in this case. Whenever our UDDI specification changed, we just uploaded the new XSD schemas in our system. Whenever the UDDI design committee decided that a given parameter must occur at least once, but not more than 5 times for example, they put it into the XSD. And through XSD validation, our code automatically checked for that condition. That saved us from spending a lot time writing and changing our input and output validation code.
All that said, there are drawbacks to this approach as well. Mainly, it feels weird if you’re coming from a pure programming perspective, and instantiating a bunch of composite classes can be a pain Once you get used to it though, it’s not so bad.
OK, enough about XSD and web service API design methodologies and back to Exchange Server 2007. Once you make the call to expand the DL, you basically get back a set of email addresses (sort of).
What you get back at first is a collection of response messages. I’m not sure when there will be more than one response to your request, maybe if there are clustered/linked Exchange servers. In any case, in any given response, there is a collection of email addresses. The double loop to go through this looks like:
I should mention, I don’t work at a fashion design firm – the context of the code being shown is for a demonstration that I’m working on
What our inner loop, as illustrated above, is working through is each member of our distribution list. Each member may be a person or another distribution list itself. I didn’t write this code, but what we should do is check for the type of member that we got back. There is an enumerated type on EmailAddressType that we can check for:
If this is another DL, I suppose you might want to go through and recursively expand each one. We won’t do that in this simple example, so let’s assume that each member we get back is just a person and not another DL.
If that’s the case, the only thing we need to do is define what our meeting time looks like:
And make the call to check the user’s availability.
I skipped some of the plumbing code – mostly setting up some of the parameter types. I’m having some trouble with my FTP server, but I’ll post the rest of my code tomorrow.
That’s about it – the next thing I’d like to look at is actually creating some lists and folders in Exchange 2007.