Exchange API-spotting

  • Attention all Exchange Web Services Solution Architects!

    If you haven't already, we strongly recommend that you review the Managing the Calendaring and Collaboration Process By Using Exchange Server 2007 Web Services Technical Case Study. In it you will find a technical case study of two internal Microsoft line-of-business applications that were migrated from earlier Exchange technologies technologies to Exchange Web Services.  Hopefully these two examples can help guide you in your design of a  service-oriented architecture that incorporates Exchange Web Services.

  • Exchange Server 2007 SP1 SDK update is now being served!

    The Microsoft Exchange Server 2007 SP1 SDK has been updated and is now available for your coding pleasure! The Exchange 2007 SP1 SDK is available for download or viewable online. We suggest that you start with the What’s New page to learn about the updates made for the August release. So get rolling on your Exchange development projects with the latest version of the Exchange SDK! And while you’re at it, take some advice from the Autodiscover song.

  • Transitioning to Exchange Web Services Notifications

    Jason Henderson announced in his Exchange Developer Roadmap blog post that we are officially deprecating, among other things, Store Event Sinks and SMTP Event Sinks. This means that Exchange developers will have to rely on Exchange Web Services (EWS) notifications and transport agents to perform many of the tasks previously handled by these event sinks. To help with the transition, I’m going to discuss how to manage the notification subscription lifecycle. Specifically, I’m going to focus on push notifications. I’m going to assume that the reader is familiar with both the Notifications documentation that is available on MSDN (Event Notifications) and the Exchange Web Services API. Also, Inside Microsoft Exchange Server 2007 Web Services is a great book that was written by some of the people who developed Exchange Web Services and has a lot of detailed information on this and other topics.

    Architecture

    Notification subscriptions (both push and pull) are stored in memory on the Client Access server (CAS). In the case of push notifications, when a subscription comes in, the CAS begins to poll the Mailbox server every couple of seconds for new events. If any events have occurred since the last poll, the Mailbox server responds to the CAS with notifications about the events and the associated watermarks. The CAS then filters these events according to the information that is provided in the subscription, and creates a notification response that is populated with those events. Along with the events, the Client Access server appends the watermark of each event, as well as the “previous” watermark – the watermark of the last event of the previous message (the Mailbox server maintains the watermarks and updates them as events occur). Finally, the CAS sends this message to the client.

    Ordering of Events

    We are frequently asked – are notifications guaranteed to arrive in the order in which the events happened? The answer is yes! When the CAS sends a notifications message to the client application, the client must reply with either an “OK” or an “Unsubscribe” response. Until the CAS receives an “OK” response, it will not send out any more NEW notifications messages (even if new events occur). It will, however, go into a retry mode, if it doesn’t receive a response within the timeout amount of time, which is set on the subscription request (this is the topic of the next section). Thus, no new notifications message will be sent out by the CAS until the previous one has been acknowledged by the server. This guarantees that the order is preserved.

    Timeouts

    We are also often asked how push notifications timeouts work. Suppose your client subscribed to push notifications, and then unexpectedly goes offline. The server will not be able to push out the next set of events as notifications to the client (or, more importantly, the server will not get a response to its notifications message). Rather than give up right away, the server will retry to push them out up to three times. After the first failure, the server will wait the timeout amount of time (that’s the timeout that you set in the subscription request) and try again. If that attempt fails, the server will wait twice the timeout time and try again. If that fails, the server will wait three times the timeout time and try again. Finally, if the third retry attempt fails, the server will give up and delete the subscription. There is no Web service method to check on the life of the subscription, but the CAS sends StatusEvent messages every timeout amount of time, so if you don’t get a StatusEvent message within the specified time, you can assume that the subscription was deleted.

    If your client application goes offline for long enough, such that the CAS went through its retry procedure and deleted the subscription, it is still possible (in almost all cases; see the next section for clarification) for your client to receive notifications that happened since the last notifications message that the client processed. To do this, you must issue a subscribe request and pass in the watermark from the point where you want to get notifications. Most of the time, you will want to pass in the last watermark seen (thus we recommend you keep track of it).

    In summary, there are really two ways to end a subscription on a CAS:

    • You can send “Unsubscribe” in the response message (as a response to a notifications message from the CAS).
    • You can become unresponsive to notifications messages.

    We recommend the first method (sending an unsubscribe message) rather than the second method, which causes the Client Access server to perform unnecessary work.

    Reliability

    Reliability of notifications is another area of confusion. Notifications are reliable – that is, all events for a mailbox that happen on the back end can be seen by the client, unless the backend server goes down. A client can always re-subscribe with the last watermark (a thing to keep in mind here: watermarks are good for about 30 days, after which they expire) and in this way get any potential events that have happened since that last watermark. The one exception to this is mailbox moves. Remember that watermarks are unique to mailbox databases, and only the Mailbox server that the watermark came from knows about that watermark. In the case of a mailbox move to another server, after the mailbox is moved, the original server notifies the CAS that no more events for that mailbox will occur, and the CAS deletes any subscriptions for that mailbox. Prior to deleting the subscriptions, the CAS will send a failure message to the client application, thus notifying it that the subscription will be deleted. The client application may now try to re-subscribe with the latest watermark. However, because the mailbox is now on another server, the previous watermarks are no longer valid (sending a subscription that includes an invalid watermark will result in an error returned by the server). Therefore, the client will have to create a new subscription from that point on. This means that any events that happened to that mailbox between the mailbox move and the creation of the new subscription creation will not be delivered.

  • Enhancing Support For Custom Item Classes

    The following proposal is a change that we’re considering for future Microsoft Exchange Server 2007 service packs and future releases of Exchange Server. Based on the feedback we’ve received, we have identified support for item classes, for which EWS doesn’t have a corresponding type, as one area where we can improve your experience with EWS. This proposed modification will change some of the default behavior, and before we make our final decision, we’d like to get your feedback.  If you are aware of any potential problems or existing coding patterns that would break as a result of this design change, please leave your comments below.
     
    BACKGROUND:
    When EWS returns an item that has an ItemClass that doesn’t map to a strong type, it returns that item as an ItemType.  For example, a developer could choose to store an item with a custom item class (i.e. “Item.Custom”) in Exchange. Because EWS doesn’t have a strong type for “Item.Custom”, the item would be returned as an ItemType.  These items create problems for EWS developers because ItemType objects cannot be sent by using the SendItem method. These items cannot be sent because they lack a number of key properties – i.e. ToRecipients, CcRecipients, Sender, and so on. Another issue developers have when working with these items is that there is no way to mark them as Read/Unread. The potential solution we’ve come up with is to have EWS return these items as messages.

     

    The MessageType derives from ItemType, so developers would gain new methods and functionality and there would be no loss of existing functionality with this solution. Exposing these additional properties would enable developers to Send, Reply, ReplyAll, and Forward these items as well as mark them as Read/Unread.

    Existing code that creates an ItemType will continue to work by using the proxy objects or XML, but those same items would be returned (via FindItem or GetItem) as MessageType objects. For these MessageType objects, you would need to look at the associated ResponseObjects property to see if Reply or ReplyAll is allowed. For example, with this change, we would return a non-delivery report (NDR) as a MessageType.  You would be allowed to forward it, but it doesn’t make sense to Reply or ReplyAll to an NDR.


    SAMPLE CODE USING PROXY OBJECTS:
    If you are using the auto-generated proxy objects, you shouldn’t notice any changes. One exception to this would be if your code is explicitly checking the item type that is returned. Because MessageType derives from ItemType, you would still be able to treat the returned item as an ItemType even though it is a MessageType.

     

    GetItemType getRequest = new GetItemType();
    getRequest.ItemIds = new BaseItemIdType[] { createResponseMessage.Items.Items[0].ItemId };
    getRequest.ItemShape = new ItemResponseShapeType();
    getRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;

    GetItemResponseType getItemRespone = esb.GetItem(getRequest);
    ItemInfoResponseMessageType getItemResponeMessage = getItemRespone.ResponseMessages.Items[0] as ItemInfoResponseMessageType;

    // If your existing application has this line of code, it will keep working regardless of whether the item coming back is an item or a message.
    ItemType returnedItem = getItemResponeMessage.Items.Items[0];

    // If you wanted to take advantage of the enhanced behavior, you would now be able to cast these items (for which we don’t have a strong type) as message.
    MessageType returnedItem = (MessageType)getItemResponeMessage.Items.Items[0];


    SAMPLE CODE USING XML: 
    The biggest change would be for developers who are sending/receiving raw XML and parsing specific nodes.  The following code will not work after this change.

     

    XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());
    namespaceManager.AddNamespace("t", @"
    http://schemas.microsoft.com/exchange/services/2006/types");
    namespaceManager.AddNamespace("m", @"
    http://schemas.microsoft.com/exchange/services/2006/messages");
    namespaceManager.AddNamespace("soap", @"
    http://schemas.xmlsoap.org/soap/envelope/");
     
    XmlDocument response = new XmlDocument();
    int xmlStartIndex = responseText.IndexOf("<?xml");
    response.LoadXml(responseText.Substring(xmlStartIndex));
    string xPath = string.Format(@"//t:Items/t:Item/t:Subject[text()='{0}']", "MySubject");
    XmlNodeList nodeList = response.SelectNodes(xPath, namespaceManager);

    After the proposed change, response.SelectNodes would not find a children of “Items” called “Item” and therefore nodeList.Count will be 0. The XPath query would need to be updated to:
    string xPath = string.Format(@"//t:Items/t:Message/t:Subject[text()='{0}']", "MySubject");


    SERVER VERSIONS:
    This proposed change will only affect requests that set the Version attribute of the RequestServerVersion SOAP header to Exchange2007_SP1. Requests made with the Version attribute set to Exchange2007, or requests where no RequestServerVersion SOAP header was specified, will continue to return these items as ItemType objects.

    EXISTING BEHAVIOR:
      <m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
         <m:ResponseMessages>
           <m:GetItemResponseMessage ResponseClass="Success">
             <m:ResponseCode>NoError</m:ResponseCode>
             <m:Items>
              
    <t:Item>
                 <t:ItemId Id="..." ChangeKey=".."/>
                 <t:ParentFolderId Id="..." ChangeKey="..."/>
                 <t:ItemClass>ABC.DEF</t:ItemClass>
                 <t:Subject>This is an ItemClass which EWS doesn’t have a strong type</t:Subject>  

         ...     
              </t:Item>
             </m:Items>
           </m:GetItemResponseMessage>
         </m:ResponseMessages>
       </m:GetItemResponse>

    PROPOSED BEHAVIOR:
      <m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
         <m:ResponseMessages>
           <m:GetItemResponseMessage ResponseClass="Success">
             <m:ResponseCode>NoError</m:ResponseCode>
             <m:Items>
              
    <t:Message>
                 <t:ItemId Id="..." ChangeKey=".."/>
                 <t:ParentFolderId Id="..." ChangeKey="..."/>
                 <t:ItemClass>ABC.DEF</t:ItemClass>
                 <t:Subject>This is an ItemClass which EWS doesn’t have a strong type</t:Subject>
                ...
                <t:ConversationIndex>AQHIueIXa5lWW0xw20qwVRcT611b/Q==</t:ConversationIndex>
                 <t:ConversationTopic>ABC.DEF</t:ConversationTopic>
                 <t:InternetMessageId>&lt;
    E4D3FFFB356BA34FAD06F517E1AECCE711C41DB278@Server.company.com&gt;</t:InternetMessageId>
                 <t:IsRead>true</t:IsRead>
              
    </t:Message>
             </m:Items>
           </m:GetItemResponseMessage>
         </m:ResponseMessages>
       </m:GetItemResponse>

    We think we’ve thought through most of the common scenarios for how people are using EWS, but this community is a rich source of customer experiences. If you are aware of any cases where this design change would cause problems, we want to know about it. Please leave your questions or comments below.

  • Exchange Developer Roadmap

    With the introduction of Exchange Web Services in Microsoft Exchange Server 2007, we began to invest in a broadly capable developer interface.  Exchange Web Services is the first Exchange API to expose rich Microsoft Office Outlook interoperability to any application in a strongly-typed, Internet accessible (HTTP-based) programming model.  Because the Exchange Web Services interfaces are based on the HTTP, XML, SOAP, and WSDL open standards, developers are free to use any platform they choose for Exchange development and application deployment.  Another great advantage of the open standards-based architecture of EWS is that there are many tools on various platforms available for creating programmatic interfaces for SOAP Web services, which makes developing against Exchange much easier than formatting and processing raw XML.  In the next version of Exchange, we will continue to invest in Web services by delivering new capabilities that provide a more efficient and optimized interface for Exchange and UC developers.

    Given this commitment to Web services and our goal of making Exchange Web Services the richest developer interface for Exchange, we want to enable developers to plan for the future by providing early information about some of the developer capabilities we expect to deliver in the next version of Exchange. 

    Here's a preview of some of the functionality that we plan to add to the next release of Exchange Web Services:

    • Access to Folder Associated Items (FAI) and read/write access to user settings
    • Management of Personal Distribution Lists
    • Throttling capabilities that give Exchange administrators control over system resource consumption
    • A powerful and easy-to-use server-to-server authentication model to enable building portals and enterprise mash-ups
    • An easy-to-use Microsoft .NET API that fully wraps the Web service calls, which makes Web service development even easier

    In addition to these enhancements to Exchange Web Services, we will continue to invest in transport extensibility, and Microsoft Windows PowerShell for Exchange administrative programmability.  

    We will also be removing duplicate legacy APIs, which we began to deemphasize in late 2005, from the next major version of Exchange.  We are removing these APIs because of architectural changes we are making to improve reliability and enable Exchange innovation.  Removing the legacy APIs and directing all applications through Exchange Web Services also significantly improves the interoperability of clients that are accessing Exchange data. This is because we can now ensure that all data access goes through a single business logic layer, the same business logic layer that Outlook Web Access, Exchange ActiveSync, Unified Messaging and many other Exchange components utilize. If you haven't already done so, we recommend that you use Exchange Web Services for new development that leverages Exchange. 

    APIs that Will Be Removed

    The following table lists the APIs that we will be removing from the next version of Exchange, provides a summary of the common uses and functions of those APIs, and lists the recommended alternatives. 

    API

    What it does

    Recommended alternative

    Exchange WebDAV

    Provides HTTP access to data in the Exchange store.

    Exchange Web Services 

    We have added a variety of features; such as ACL support and Public Folder access to Exchange Web Services in Exchange 2007 SP1 to replace Exchange WebDAV functionality and are continuing to invest in additional functionality in the next release of Exchange. 

    Store Events

    Synchronous or asynchronous events running on the Store, either in-process (scripts via a wrapper, COM objects) or out-of-process (via COM+); includes methods such as OnSave, OnDelete, OnSyncSave, and OnSyncDelete.

    Exchange Web Services Push and Pull notifications for general asynchronous notifications and Transport agents for synchronous mail delivery event functionality. 

    In Exchange 2007 we enabled transport rules, in addition to transport extensibility, that enable administrative control over mail flow based on sender, recipient, and message content.  In the next release of Exchange, we are extending the capabilities of transport rules to enable a number of mail flow control scenarios without having to build a custom transport agent and enabling administrator-defined inbox rules that allow for control over the delivery of messages to the end user's mailbox. 

    Synchronous events for non-mail delivery scenarios will not be supported in the next version of Exchange.  Removing synchronous notifications will improve the reliability of Exchange and prevent data corruption issues that were often seen when applications did not save an item correctly during a multi-phase synchronous commit to the store.

    CDO 3.0 (CDOEx)

    Provides access to local Exchange data.

    Exchange Web Services

    Exchange Web Services has support for calendaring, contacts and other PIM data as strongly-typed objects.

    ExOLEDB

    Provides access to the Exchange store by using OLE DB and Active Data Objects (ADO).

    Exchange Web Services or VSAPI

    Exchange Web Services has support for PIM access, for antivirus solutions built on ExOleDB, the Exchange Virus Scan API (VSAPI) can be used to achieve similar results.

     

    APIs Moving To Extended Support

    In addition to the APIs that we will be removing from the next version of Exchange, developers should be aware of the support lifecycle for several Exchange client libraries.  The Exchange Server MAPI Client and Collaboration Data Object 1.2.1 (CDO 1.2.1) downloads are part of the Exchange 2003 codebase and will be moving to extended support together with Exchange 2003 early next year.

    The following table lists the recommended alternatives for the APIs that will be moving into extended support.

    API

    What it does

    Recommended alternative

    Exchange Server MAPI Client

    Provides server applications a MAPI runtime for accessing Exchange. 

    Note: This is not the Outlook MAPI Client library that is included with Outlook.

    Exchange Web Services or Outlook MAPI Client library

    Exchange Web Services can be used to achieve much of the same functionality as the Exchange Server MAPI Client.

    Outlook's Exchange MAPI Store provider, available in the Outlook MAPI Client library can also be used to access an Exchange mailbox or public folder.

    Collaboration Data Objects 1.2.1 (CDO 1.2.1)

    Provides access to mail, calendar, and contacts data in Exchange.

    Exchange Web Services, Outlook Object Model, Outlook MAPI Client library

    Exchange Web Services should be used for general Exchange data access by services or server applications. The Outlook Object Model or Outlook MAPI Client library should be used for client applications.

     

    Because the Exchange Server MAPI Client and CDO 1.2.1 APIs are moving out of standard support, we no longer recommend writing new applications against these libraries.  All new application development should be done against Exchange Web Services, the Outlook Object Model or the Outlook MAPI Client library.

    To ease migration, the CDO 1.2.1 and Exchange MAPI client legacy libraries will remain available for download after they move to extended support.  The use of these libraries against the next release of Exchange will be supported; however, these libraries will not be updated with new functionality or shipped in a 64-bit version. For new functionality and true 64-bit support, your application will have to use Exchange Web Services, the Outlook Object Model, or the Outlook MAPI Client library.

    To get started with Exchange Web Services or transport extensibility, check out the Exchange 2007 SP1 SDK on MSDN, the Exchange Server Developer Center, and the Exchange Development Forums. For an in-depth reference for developing with Exchange Web Services, see Inside Microsoft Exchange Server 2007 Web Services, which was recently written by members of the development, test, and documentation teams.  To learn more about the Outlook Object Model, visit the Outlook 2007 Resource Center. If you are going to be at TechEd in Orlando next month stop by and listen to our talk on migrating your application to Exchange Web Services.

    Our documentation team will start publishing migration documentation in early June to help you with the transition.  Keep your eye on this blog and the Exchange Developer Center in coming months for more information to help you with your migration planning.  The Exchange documentation team would love to receive feedback on which type of documentation that would be most useful to you.  Drop an e-mail message to esdkfb@microsoft.com with your opinions.  The Exchange Web Services team would also like to hear your thoughts on what you want to see in the next release of Exchange, so drop us a message at ewsfdbck@microsoft.com.

     

  • Incremental Change Synchronization API Definitions

    The following interfaces and properties are defined in the Exchange header file edkmdb.h. They are provided here in case your application has to use them, and you are unsure of their function.

    Applications implement interfaces according to the IExchangeImportContentsChanges definition. The interface that is used by the Incremental Change Synchronization (ICS) system can notify the application when changes to the mailbox content have occurred. The interface is registered for callback when you configure the synchronizer object that is returned by the MAPI folder object.

    The interface definition is commented-out in the header file edkmdb.h because Exchange does not actually implement the interface. The application implements the interface.

    // IExchangeImportContentsChanges
        STDMETHOD(GetLastError)(HRESULT hResult, ULONG ulFlags, __in LPMAPIERROR *lppMAPIError);
        STDMETHOD(Config)(__in LPSTREAM lpStream, ULONG ulFlags);
        STDMETHOD(UpdateState)(__in LPSTREAM lpStream);
        STDMETHOD(ImportMessageChange)
            (ULONG cpvalChanges, __in LPSPropValue ppvalChanges, ULONG ulFlags, __in LPMESSAGE *lppMessage);
        STDMETHOD(ImportMessageDeletion)(ULONG ulFlags, __in LPENTRYLIST lpSrcEntryList);
        STDMETHOD(ImportPerUserReadStateChange)(ULONG cElements, __in LPREADSTATE lpReadState);
        STDMETHOD(ImportMessageMove)
            (ULONG cbSourceKeySrcFolder, __in BYTE *pbSourceKeySrcFolder,
             ULONG cbSourceKeySrcMessage, __in BYTE *pbSourceKeySrcMessage,
             ULONG cbPCLMessage, __in BYTE *pbPCLMessage,
             ULONG cbSourceKeyDestMessage, __in BYTE *pbSourceKeyDestMessage,
             ULONG cbChangeNumDestMessage, __in BYTE *pbChangeNumDestMessage)

    The following interface definition, found in the edkmdb.h header file, is returned by the MAPI folder object. Configure the object properties using the object methods, and then call the Synchronize method to register the custom ExchangeImportContentsChanges callback routine of your application.

    #define EXCHANGE_IEXCHANGEEXPORTCHANGES_METHODS(IPURE)      \
        MAPIMETHOD(GetLastError)                                \
           (THIS_ HRESULT hResult,                              \
            ULONG ulFlags,                                      \
            LPMAPIERROR FAR * lppMAPIError) IPURE;              \
        MAPIMETHOD(Config)                                      \
           (THIS_ LPSTREAM lpStream,                            \
            ULONG ulFlags,                                      \
            LPUNKNOWN lpUnk,                                    \
            LPSRestriction lpRestriction,                       \
            LPSPropTagArray lpIncludeProps,                     \
            LPSPropTagArray lpExcludeProps,                     \
            ULONG ulBufferSize) IPURE;                          \
        MAPIMETHOD(Synchronize)                                 \
           (THIS_ ULONG FAR * lpulSteps,                        \
            ULONG FAR * lpulProgress) IPURE;                    \
        MAPIMETHOD(UpdateState)                                 \
           (THIS_ LPSTREAM lpStream) IPURE;
    #undef INTERFACE

    The PR_CONTENTS_SYNCHRONIZER property is used to request a pointer to the IExchangeExportChanges object. Note that the PT_Object and PROP_TAG are also defined in the edkmdb.h header file.

    #define pidStoreMin 0x6618
    #define PR_CONTENTS_SYNCHRONIZER PROP_TAG( PT_OBJECT, pidStoreMin+0x15)

    The following flags instruct ICS as to what types of changes the application is interested in receiving.

    /*------------------------------------------------------------------------
     *
     *     Flags used by Exchange Incremental Change Synchronization Interface
     *
     *-----------------------------------------------------------------------*/
    #define SYNC_UNICODE                         0x01
    #define SYNC_NO_DELETIONS                    0x02
    #define SYNC_NO_SOFT_DELETIONS                   0x04
    #define SYNC_READ_STATE                      0x08
    #define SYNC_ASSOCIATED                      0x10
    #define SYNC_NORMAL                          0x20
    #define SYNC_NO_CONFLICTS                    0x40
    #define SYNC_ONLY_SPECIFIED_PROPS            0x80
    #define SYNC_NO_FOREIGN_KEYS                 0x100
    #define SYNC_LIMITED_IMESSAGE                0x200
    #define SYNC_CATCHUP                         0x400
    #define SYNC_NEW_MESSAGE                     0x800 // only applicable to ImportMessageChange()
    #define SYNC_MSG_SELECTIVE                   0x1000 // Used internally. Will reject if used by clients.
    #define SYNC_BEST_BODY                       0x2000
    #define SYNC_IGNORE_SPECIFIED_ON_ASSOCIATED  0x4000
    #define SYNC_PROGRESS_MODE                   0x8000 // AirMapi progress mode
    #define SYNC_FXRECOVERMODE                   0x10000
    #define SYNC_DEFER_CONFIG                    0x20000
    #define SYNC_FORCE_UNICODE                   0x40000 // Forces server to return Unicode properties

    When combined with the others defined in the ebkmdb.h, the following bit-field definitions are used to indicate the scope of changes that Exchange ICS will report to the application:

    #define CONVENIENT_DEPTH  ((ULONG) 0x00000001
    #define SHOW_SOFT_DELETES ((ULONG) 0x00000002)
    #define SHOW_SUBFOLDERS   ((ULONG 0x00000004)

    The PR_LOCAL_COMMIT_TIME_MAX property, which is returned for a folder, indicates when any items in the folder were last changed. When this property value is different from the PR_LOCAL_COMMIT_TIME property value, items in the folder have changed since the last time changes to the folder were committed to the database.

    #define pidAdminMin 0x6690
    #define PR_LOCAL_COMMIT_TIME_MAX PROP_TAG(PT_SYSTIME, pidAdminMin+0x7a)

    The PR_DELETED_COUNT_TOTAL property indicates how many items have been deleted from the folder since the folder was created.

    #define pidAdminMin 0x6690
    #define PR_DELETED_COUNT_TOTAL PROP_TAG(PT_LONG, pidAdminMin+0x7b)

  • Erratum - Exchange Server 2007 SP1 SDK November 2007 Readme

    The Readme for the November 2007 release of the Exchange Server 2007 SP1 SDK include an error. The following statement in the Readme is incorrect:

    By default, the Setup wizard installs the Exchange Server 2007 SP1 SDK Documentation and Samples on the drive that contains the operating system (usually drive C), in the folder \Program Files\Exchange Server 2007 SP1 SDK\.

    The statement should read as follows:

    By default, the Setup wizard installs the Exchange Server 2007 SP1 SDK Documentation and Samples on the drive that contains the operating system (usually drive C), in the folder \Program Files\Microsoft\Exchange Server 2007 SP1 SDK\November 2007.

    This error is fixed in the online version of the Readme, but is still exists in the Readme that is included in the downloadable version of the SDK.

  • Discover Autodiscover!

    One of the most frequent mistakes that we see developers who are using Exchange Web Services make is the hard-coding of the URL for the ExchangeServiceBinding to a specific location.  Hard-coding the URL is not recommended, especially given that Exchange Web Services provides a mechanism for avoiding this: Autodiscover.  Autodiscover ensures that your client is always returned the most efficient URL to use for a given mailbox.  Are you wondering why we don’t recommend hard-coding the URL?  Let me count the ways!

    1.       The hard-coded URL might point to the URL of a Client Access server that is in a different site from the user’s mailbox.  Accessing a Client Access server in a different site from a user’s mailbox results in poorer performance and greater complexity than accessing a Client Access server in the same site as the mailbox. The only way to ensure that you are accessing a Client Access server in a particular user’s site is to use Autodiscover.

    2.       We may change the URL for various Web services as we consolidate them, or break them up for better architecture between roles, which will complicate migration to later versions of Microsoft Exchange Server. 

    3.       The corporate address could change namespaces (this doesn’t happen often, but we have occasionally changed our namespace at Microsoft).  For example, https://mail.contoso.com could become https://portal.contoso.com.

    Let me explain a little more about why accessing a Client Access server in a different site from a user’s mailbox is not a good idea. If your enterprise has multiple Active Directory sites (i.e. branch offices that are running Exchange Server 2007), Exchange Web Services in the initial release version of Exchange 2007 will be making cross-site remote procedure calls (RPCs) from the Client Access server that you are accessing to the mailbox in the site where a user is located.  Cross-site RPCs are not recommended because RPC traffic is very chatty and high latency networks between sites will degrade the performance of Exchange Web Services significantly.  In Exchange 2007 Service Pack 1 (SP1), we have gone the route of Outlook Web Access and ActiveSync and disabled cross-site RPC functionality.  Now cross-site calls will fail unless an Exchange 2007 SP1 Client Access server is in the same site as the user mailbox that is set up for EWS proxy.  EWS proxy makes these requests more efficient by sending a single HTTP request rather than multiple RPC requests.  However, relying on EWS proxy to do the work of getting your request to the right site is also not an ideal solution because it puts unnecessary load on the proxying Client Access server. You can avoid this unnecessary load by making the request to the appropriate Client Access server yourself.

    We have some good resources about using Autodiscover. For a sample application that includes downloadable source code that implements an Autodiscover client for you, see Autodiscover Sample Application. For information about the structure of an Autodiscover request, see Autodiscover Request.

    One thing to note: Autodiscover is not a SOAP-based Web service.  It just uses plain old XML (POX).

    Look for more information that describes Autodiscover in more depth soon. Until then, use the examples referenced earlier and always Autodiscover. 

     

  • Generating Exchange Web Services Proxy Classes

    It has come to our attention that there has been some confusion over the mention of EWS.dll in the SDK documentation and Intellisense file. Where can people find it? Actually, you get to generate it. The Exchange 2007 SDK describes how to generate proxy classes by using the Add Web Reference. This may be fine for some of you, but others may want more flexibility with their proxy classes. This is where wsdl.exe comes into the picture. 

    Wsdl.exe parses schema and WSDL files to generate Microsoft .NET code files. These code files contain the types that act as proxies for the serialization and deserialization of the XML messages that are sent to and from the Exchange server. Wsdl.exe is included in the .NET Framework SDK and with Visual Studio 2003 and 2005. Different proxy generators create different object models; in this discussion, I will focus on wsdl.exe version 2.0.50727.42, the version that is included with Visual Studio 2005.

    Instead of using wsdl.exe, you can use the Add Web References option in Visual Studio 2005 to create proxy classes. (This option will still be available in Visual Studio 2008, except that it will be well hidden). I prefer to use wsdl.exe to generate my proxy classes, for two reasons: 1) I can easily extend the proxy classes to make them easier to use, and 2) I can reuse my compiled DLL in all my Exchange Web Services projects. If I use the Add Web References option in Visual Studio, I have to regenerate the proxy classes for each project and therefore I lose any modifications that I made to the autogenerated classes. Oh, and remember that changes made to autogenerated classes are not supported by Microsoft; you are on your own with those modifications.

    Let's start by finding wsdl.exe. By default, the Windows SDK installs it to C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\wsdl.exe. You can also access wsdl.exe by using the Visual Studio 2005 Command Prompt. To find the Visual Studio 2005 Command Prompt, from the Start Menu, choose All Programs | Microsoft Visual Studio 2005 | Visual Studio Tools | Visual Studio 2005 Command Prompt. Wsdl.exe has been added to the Path environment variable of the Visual Studio 2005 Command Prompt so that you can access it easily.

    Now that you know where to find wsdl.exe, you can learn more about it by reading the Web Services Description Language Tool (Wsdl.exe) topic.

    You are now ready to generate the proxy classes. I like to use the Visual Studio 2005 Command Prompt to access wsdl.exe as it also has the C# compiler in the path. We will use the C# compiler in a bit. In the Visual Studio 2005 Command Prompt, I use the following parameters to generate my proxy classes:

    wsdl /language:cs /out:EWS.cs /namespace:ExchangeWebServices https://MyCAServer.Domain.com/ews/services.wsdl

    I chose C# as the output language type for my proxy classes. You can also use Visual Basic .NET or C++ proxy classes. EWS.cs is the output code file for my proxy classes. I used ExchangeWebServices for the name of the namespace that holds all the proxy types; this is consistent with the namespace that is used in the Exchange 2007 SDK documentation and the Intellisense files that are included in the downloadable SDK. The last argument is the URL to my Exchange Web Services endpoint.

    So now you have a code file with the autogenerated proxies. Next, you compile your code file into an assembly for use in your Exchange Web Services projects. The C# compiler is available with the Visual Studio 2005 Command Prompt. Assuming that you named your code file EWS.cs, you can run the following command at the command prompt to compile your code into an assembly:

    csc /target:library /out:EWS.dll EWS.cs

    Notice that EWS.dll is the name of the compiled assembly. This is how EWS.dll is created.

    Voila! Now you have an assembly that can be reused in all your Exchange Web Service projects. If you currently use the Add Web References option in Visual Studio 2005, I recommend that you start using wsdl.exe instead to generate your Exchange Web Services proxy classes.

  • Exchange Server 2007 SP1 is here - and so is the SDK!

    As reported on the Microsoft Exchange Team Blog, Service Pack 1 for Exchange Server 2007 has been released! The Microsoft Exchange Server 2007 SP1 SDK is also available online and for download. If you want to find out about the changes for developers in Exchange 2007 SP1, including additions to transport extensibility, Exchange Web Services, and Outlook Web Access customization, check out the What's New in Exchange Server 2007 SP1 Extensibility article.

    There's a lot of good stuff in SP1. Go learn. Go develop!

  • Updating Exchange Server 2007 Exchange Web Service Clients to SP1

    Exchange Server 2007 Service Pack 1 is coming soon! The service pack includes some Exchange Web Services–related changes that we think you should know about. In fact, you will want to become familiar with these changes so that you can update your client applications to use the new functionality.

    For starters, we’ve added enhanced delegate access, delegate management, folder-level permissions, public folder access, and identifier translation. For more information about these features, check out the What's New in Exchange Server 2007 SP1 Extensibility article. Consider adding this functionality to your EWS client applications. We’ve also added a new version SOAP header that is used to distinguish client applications, and the schemas they use, between the initial release and SP1 versions of Exchange 2007.

    Overall, we encourage you to update your EWS applications to use proxy classes that are generated against the schemas that are included in Exchange 2007 SP1. Use the SP1 version header to distinguish the request as coming from an SP1-compliant client application. Client applications that send requests to Exchange 2007 SP1 servers that use the SP1 release version of the Web service schemas must specify the Exchange2007_SP1 enumeration value as the version header. Otherwise, requests that are sent to a Client Access server are assumed to be from Exchange 2007 client applications. These requests are validated against the initial release version of the EWS schemas. Therefore, any clients that use autogenerated proxy classes that are created from the SP1 schemas should use the version headers to distinguish the request version. Any client application that has been upgraded to send requests and receive responses based on the SP1 schemas should also use the version header.

    Here is an example of how to set the version on the ExchangeServiceBinding to represent an Exchange 2007 SP1 request:

    ExchangeServiceBinding esb = new ExchangeServiceBinding();
    esb.RequestServerVersionValue = new RequestServerVersion();
    esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;

    Here is the XML that describes the SOAP header that represents an SP1 request. This is the same XML that is created by the RequestServerVersionValue property of the ExchangeServiceBinding object:

    <soap:Header>
      <t:RequestServerVersion Version="Exchange2007_SP1"/>
    </soap:Header>

    Another important change in Exchange 2007 SP1 is the use of a new identifier format. The identifier format that was included in the initial release version of Exchange 2007 was partially based on SMTP addresses. However, SMTP addresses can change. Therefore, if a client is caching identifier information and an SMTP address changes, any attempts to use those cached identifiers in subsequent requests will fail because the identifier was formed using an outdated SMTP address. This requires a client to resynchronize with the Exchange server any time the primary SMTP address changes. In Exchange 2007 SP1, the identifier is partially based on a unique mailbox identifier that does not change. By default, in both Exchange 2007 and Exchange 2007 SP1, requests are validated against the Exchange 2007 version of the schema, which is the schema that is included in build 685.024.

    The following table lists the possible identifier scenarios and how requests are handled for each.

    Scenarios for requests against Exchange 2007 SP1 target servers

    Identifier Version Version Header Outcome
    E2K7 SP1 Not set Schema validation error
    E2K7 SP1 Exchange2007 Schema validation error
    E2K7 SP1 Exchange2007_SP1 Successful request
    E2K7 Not set Successful request; same behavior as request sent against the initial release of E2K7
    E2K7 Exchange2007 Successful request; same behavior as request sent against the initial release of E2K7
    E2K7 Exchange2007_SP1 Schema validation error

    But wait! There are other reasons to migrate to Exchange 2007 SP1. The SP1 version of Exchange Web Services also includes the following improvements:

    1. Better time zone support. See Working with Time Zones in the Exchange Web Services GetUserAvailability Operation for more information.
    2. Improved error responses.
    3. The Proxy to Best CAS feature. Client Access servers now proxy requests to the most appropriate Client Access server to service a mailbox. This functionality is independent of the version header in the SOAP request.
    4. Other updates that might affect product behavior. Be sure to retest your client applications after you install Exchange 2007 SP1.

    You now have some compelling reasons to install Exchange Server 2007 SP1. So join the Beta fun and download SP1 Beta 2 to learn more about these exciting new features. And while you’re at it, provide us with some feedback through the Exchange Development forum.

  • Exchange Server 2007 SDK has been updated!

    The Exchange Developer Documentation Team is happy to announce the July 2007 release of the Exchange Server 2007 SDK. Read the What's New topic to find out what we added in this release. If you’re working with Exchange Web Services, review the new documentation that covers some of the autogenerated proxy types. And if you like installing the SDK and samples locally, download the SDK here.

    Thanks again for stopping by our blog.

    Michael Mainer
    Microsoft Corporation

  • New and improved - We updated the TechReady 2007 Talk article download

    If you downloaded the code samples for the Exchange Server Developer Center article TechReady 2007 Talk: Developing With Exchange Web Services, you probably had some problems building the projects, because some of the files didn't make it into the download packages.

    We've corrected that and the updated download packages now contain all the files you need to successfully build the projects. We also updated the Readme file with instructions about how to replace the reference to the Exchange Web Services end point, so the projects use your Exchange Web Services installation.

    You can find both the English (TechReady2007EWS-en.exe) and French (TechReady2007EWS-fr.exe) download packages on the TechReady 2007 Exchange Web Services Samples download page.

  • Exchange Developer Documentation Team Wants YOU!

    If you’re reading this, you’re VERY likely a developer with at least some Exchange experience. Well, we need you. Really. The Exchange Developer Documentation team has an open position for a Programming Writer. If you want to help improve the Exchange Developer Center, if you want to write cool code samples and clear documentation, if you want a direct connection with both the product team and the developer community, contact me (thomr@microsoft.com) today!

    To get an idea what it’s like to work in my team, let’s just say a healthy sense of humor is a plus. The team enjoys working together, we encourage finding innovative ways to create and present developer-focused materials, and we are given the freedom to implement those ideas. We publish the SDKs every few months, technical articles every month, and blog posts like this one at random intervals. We work very closely with the product team, as well as Marketing, and our dear friends in MSDN.

    If you like what we’re doing, and want to help us add more information and try new ways of reaching out to the Exchange developer community, give us a ring. We’re looking for someone with a well-balanced mix of writing ability (good writing, excellent organizational skills), development experience (VS.NET, a variety of languages, Web services), and knowledge about one or more Exchange programming technologies. Yeah, sure we’re flexible on those. You do NOT need to be a professional writer with a bunch of books in your name. You do NOT need to be a guru-level Exchange solution developer. But, let’s face it: if you ARE those things, we'd love to hear from you! You will definitely need to learn quickly and understand complex technologies clearly enough to explain them to others.

    On a daily basis we all do a bit of writing, programming, debugging, looking at product source code to understand how an API works, planning for the next release, and answering questions from a variety of good-natured people. We sit in meetings, we go to lunch, and do all the normal things of working for a living at Microsoft.

    To get the official scoop on the position, check it out here . Give me a call (425-705-8271) or e-mail your resume (thomr@microsoft.com) if you think you might fit well here.  Ray, Laura, Michael and I would like to meet you! And of course, if you know someone else who might fit our needs, be sure to send them our way!

    Thom Randolph
    Documentation Manager
    Exchange Developer Documentation
    Microsoft Corporation

  • Microsoft Office Workflow Designer for Exchange is no longer available

    Starting in May 2007, the Workflow Designer for Exchange, and the Exchange SDK Workflow Application Templates will no longer be available for download. Support for existing installations of the Workflow Designer for Exchange (ExWFD) and templates will continue until support for Microsoft Exchange Server 2003 ends.

    Contact Microsoft CSS if you need the ExWFD installation package.  You can find a complete list of Microsoft Customer Support Services telephone numbers and other information http://support.microsoft.com/contactus/?ws=support.

    If you’re creating new workflow-based applications, we recommend using the Windows Workflow Foundation. If you’re maintaining existing applications based on Exchange workflow, consider moving to the Workflow Foundation if the application needs to stay in service for more than a couple years.

    What is this WF thing?

    Windows Workflow Foundation (WF) is a programming model, orchestration engine, and design tools for quickly building workflow-enabled applications on Windows. WF consists of a .NET Framework namespace, an in-process workflow engine, and designers for Visual Studio 2005. Windows Workflow Foundation applications can be developed and run on Windows Vista, Windows XP, and the Windows Server 2003 family. Windows Workflow Foundation includes support for both system workflow and human workflow across a variety of scenarios. Line-of-business applications, user interface page-flow, document-centric workflow, human workflow, service-oriented composite workflows, business rule-driven workflows, and workflow for systems management are only a few of the applications where WF excels.

    Yeah, but Exchange Workflow worked fine for my needs…

    There are several reasons why moving away from Exchange Workflow and the Workflow Designer for Exchange, and moving to WF is the right thing:

    - WF is Microsoft’s strategic direction for workflow applications.

    - WF leverages current technology and a better programming model.

    - WF can be used in managed code (ExWFD and CDOWF cannot).

    - WF will also be used in other Microsoft applications.

    - ExWFD and CDOWF are not compatible with Microsoft Exchange Server 2007.

    Need some links?

    These links provide more information on the Windows Workflow Foundation.

    Windows Workflow Foundation Overview:
    http://msdn2.microsoft.com/en-us/library/ms734631.aspx

    Windows Workflow Foundation Programming Guide:
    http://msdn2.microsoft.com/en-us/library/ms734702.aspx

    Windows Workflow Foundation Tutorials:
    http://msdn2.microsoft.com/en-us/library/ms735927.aspx

    Windows Workflow Foundation Samples:
    http://msdn2.microsoft.com/en-us/library/ms741723.aspx

    Visual Studio 2005 Designer for Windows Workflow Foundation Overview:
    http://msdn2.microsoft.com/en-us/library/ms441543.aspx

    Windows Workflow Foundation Developer Center:
    http://msdn2.microsoft.com/en-us/netframework/aa663328.aspx

    Introduction to workflows on the Microsoft Office SharePoint Server site:
    http://office.microsoft.com/en-us/sharepointserver/HA101544241033.aspx?pid=CH101782961033

    Understanding Workflow in Windows SharePoint Services and the 2007 Microsoft Office System (5Mb Word Format):
    http://www.microsoft.com/downloads/details.aspx?FamilyId=DBBD82C7-9BDE-4974-8443-67B8F30126A8&displaylang=en

More Posts Next page »

© 2008 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker