Exchange Web Services Responses

Topic Last Modified: 2007-04-13

The response types that are created in a Microsoft Visual Studio 2005 proxy for Exchange Web Services provide a set of properties that represent the status of the requested operation, item-specific information, and other information stored as a descendant of the ResponseMessageType class. With the exception of the GetUserAvailability and GetUserOofSettings responses, all response information is returned in the ResponseMessageType class.

The ResponseMessageType class is the base class for all response messages. It contains the response code, the response class, and additional information about a request. Many requests return response message types that extend the ResponseMessageType class. For example, the GetItem operation returns an ItemInfoResponseMessageType object, which extends the ResponseMessageType class with additional information that describes items.

The GetUserOofSettingsResponse and GetUserAvailabilityResponseType responses contain types that provide response information in addition to the information provided in the ResponseMessageType class.

To better understand how to access properties returned in the response messages, review the types.xsd and messages.xsd schema files and compare the structure of the XML to the structure of the proxy object model.

Accessing Response Messages

To access the ResponseMessageType class for all responses other than the GetUserAvailability, GetUserOofSettings, and SetUserOofSettings responses, you must access the ArrayOfResponseMessagesType class that is returned by the ResponseMessages property of the response. The following example shows how to access the ResponseMessageType for the CreateItem method. The esb object that calls the CreateItem method is the ExchangeServiceBinding object.

// Send a CreateItem request and get the CreateItem response.
CreateItemResponseType createItemResponse = esb.CreateItem(createItemRequest);
ArrayOfResponseMessagesType responseMessages = createItemResponse.ResponseMessages;

// Access the response message.
ResponseMessageType responseMessage = responseMessages.Items[0];

To access information that is specific to the request type, you must cast the ResponseMessageType class to the correct type. The following table describes the type of cast that must be performed on the ResponseMessageType class to get the requested information. Note that many requests only return the ResponseMessageType class.

Request Returned response type ResponseMessage Cast As

CreateItem

CreateItemResponseType

ItemInfoResponseMessageType

GetItem

GetItemResponseType

ItemInfoResponseMessageType

UpdateItem

UpdateItemResponseType

ItemInfoResponseMessageType

MoveItem

MoveItemResponseType

ItemInfoResponseMessageType

CopyItem

CopyItemResponseType

ItemInfoResponseMessageType

FindItem

FindItemResponseType

FindItemResponseMessageType

CreateManagedFolder

CreateManagedFolderResponseType

FolderInfoResponseMessageType

CreateFolder

CreateFolderResponseType

FolderInfoResponseMessageType

GetFolder

GetFolderResponseType

FolderInfoResponseMessageType

UpdateFolder

UpdateFolderResponseType

FolderInfoResponseMessageType

MoveFolder

MoveFolderResponseType

FolderInfoResponseMessageType

CopyFolder

CopyFolderResponseType

FolderInfoResponseMessageType

FindFolder

FindFolderResponseType

FindFolderResponseMessageType

DeleteItem

DeleteItemResponseType

N/A

SendItem

SendItemResponseType

N/A

DeleteFolder

DeleteFolderResponseType

N/A

CreateAttachment

CreateAttachmentResponseType

AttachmentInfoResponseMessageType

GetAttachment

GetAttachmentResponseType

AttachmentInfoResponseMessageType

DeleteAttachment

DeleteAttachmentResponseType

DeleteAttachmentResponseMessageType

ResolveNames

ResolveNamesResponseType

ResolveNamesResponseMessageType

ExpandDL

ExpandDLResponseType

ExpandDLResponseMessageType

GetEvents

GetEventsResponseType

GetEventsResponseMessageType

Subscribe

SubscribeResponseType

SubscribeResponseMessageType

Unsubscribe

UnsubscribeResponseType

N/A

SendNotification

SendNotificationResponseType

SendNotificationResponseMessageType

SyncFolderHierarchy

SyncFolderHierarchyResponseType

SyncFolderHierarchyResponseMessageType

SyncFolderItems

SyncFolderItemsResponseType

SyncFolderItemsResponseMessageType

SetUserOofSettings

SetUserOofSettingsResponse

N/A

GetUserOofSettings

GetUserOofSettingsResponse

N/A

GetUserAvailability

GetUserAvailabilityResponseType

N/A

Note

DeleteItem, SendItem, DeleteFolder, and Unsubscribe return only the status of the request in the ResponseMessageType. Because they do not return any additional information, they do not extend the ResponseMessageType class.

You must cast the ResponseMessageType class to another type for classes that extend the ResponseMessageType class. So, for a CreateItem response, you must cast the ResponseMessageType class to the ItemInfoResponseMessageType class, as shown in the following example.

if (responseMessage is ItemInfoResponseMessageType)
{
   ItemInfoResponseMessageType iirmt = (responseMessage as ItemInfoResponseMessageType);
}

Important

Refer to the schema files to determine the appropriate cast for an item. For more information about how the choice schema element affects the proxy assembly, see XML Schema Choice Element Proxy Artifacts.

ItemInfoResponseMessageType

The ItemInfoResponseMessageType class can contain an array of different item types. It is important to type check each item that is returned in the array to determine the appropriate cast for the item. For example, because a CreateItem request can create many types of items, the CreateItem response can also contain information about different item types. The ItemInfoResponseMessageType class contains an Items property that returns an ArrayOfRealItemsType object. The ArrayOfRealItemsType object contains a single Items property that returns an ItemType[]. Each item in the ItemType[] must be type-checked and cast to the appropriate item type if type-specific information is requested. Otherwise, if the properties to be retrieved are from the base type, a cast is unnecessary. For information about why this pattern exists, see XML Schema Choice Element Proxy Artifacts.

The following code example shows how to type check each item and cast to the appropriate type.

ItemInfoResponseMessageType createItemResp = (responseMessage as ItemInfoResponseMessageType);
ArrayOfRealItemsType aorit = createItemResp.Items;

foreach (ItemType item in aorit.Items)
{
    if (item is ItemType)
    {
        ItemType myItem = (item as ItemType);
    }
    if (item is MessageType)
    {
        MessageType myMessage = (item as MessageType);
    }

    // TODO: Add logic to check and cast for all other types.
}

For all the possible casts, see the ArrayOfRealItemsType complexType type in the types.xsd schema file.

FindItemResponseMessageType

The FindItemResponseMessageType type is only used in FindItem responses. It contains either an ArrayOfGroupedItemsType or an ArrayOfRealItemsType object. Because the two possible result set types are defined in a XML schema choice element, the proxy generator in Visual Studio 2005 cannot determine which type of object is returned in the response. The client application must type check to determine whether the response is grouped or not.

The following code example shows how to handle a FindItem response.

FindItemResponseMessageType firmt = (responseMessage as FindItemResponseMessageType);
FindItemParentType fipt = firmt.RootFolder;
object obj = fipt.Item;

// Determine whether the FindItem request was a grouped request.
if (obj is ArrayOfGroupedItemsType)
{
    ArrayOfGroupedItemsType groupedItems = (obj as ArrayOfGroupedItemsType);
    //TODO: Write code to handle grouped items.
}
else if (obj is ArrayOfRealItemsType)
{
    ArrayOfRealItemsType items = (obj as ArrayOfRealItemsType);
    //TODO: Write code to handle items.
}

Note

A grouped items response will only occur if you search by using the GroupBy option.

The following XML is from the types.xsd schema file. This shows the XML schema choice element and the instance elements that are part of the choice.

<xs:complexType name="FindItemParentType">
  <xs:choice>
    <xs:element name="Items" type="t:ArrayOfRealItemsType"/>
    <xs:element name="Groups" type="t:ArrayOfGroupedItemsType"/>
  </xs:choice>
  <xs:attributeGroup ref="t:FindResponsePagingAttributes"/>
</xs:complexType>

FolderInfoResponseMessageType

The FolderInfoResponseMessageType class contains information about folders. It can contain information about folders, calendar folders, contacts folders, search folders, and task folders. All folders share the BaseFolderType base class. The SearchFolderType and TasksFolderType types extend the FolderType class.

The FolderInfoResponseMessageType class contains a Folders property that returns a BaseFolderType[]. Each folder in the BaseFolderType[] must be type checked and cast to the appropriate type so that all the properties can be accessed on the folder. The following code example shows how to access the different folder types.

// Get the response messages.
ResponseMessageType[] rmta = response.ResponseMessages.Items;

foreach (ResponseMessageType responseMessage in rmta)
{
    FolderInfoResponseMessageType firmt = (responseMessage as FolderInfoResponseMessageType);
    BaseFolderType[] folders = firmt.Folders;

    foreach (BaseFolderType folder in folders)
    {
        if (folder is TasksFolderType)
        {
            TasksFolderType tft = (folder as TasksFolderType);
            //TODO: Handle the task folder.
        }

        else if (folder is CalendarFolderType)
        {
            CalendarFolderType cft = (folder as CalendarFolderType);
            // TODO: Handle the calendar folder.
        }

        else
        {
            //TODO: Handle the FolderType, SearchFolderType, and ContactsFolderType folders.
        }
    }
}

Note

In the CreateFolder operation, only task folders can be type checked. All other folder types are returned as the base FolderType class. Other folder operations will have different behavior.

FindFolderResponseMessageType

The FindFolderResponseMessageType type provides the search results of a FindFolder query. The following example shows how to access the search results and how to cast the BaseFolderType to an actual folder type.

// Get the response messages.
ResponseMessageType[] rmta = findFolderResponse.ResponseMessages.Items;

foreach (ResponseMessageType rmt in rmta)
{
    FindFolderResponseMessageType ffrmt = (rmt as FindFolderResponseMessageType);
    FindFolderParentType ffpt = ffrmt.RootFolder;
    BaseFolderType[] folders = ffpt.Folders;
    
    foreach (BaseFolderType folder in folders)
    {
        // Determine the folder type.
        if (folder is CalendarFolderType)
        {
            CalendarFolderType fldr = (folder as CalendarFolderType);
            // TODO: Handle calendar folder.
        }
        else 
        { 
            // TODO: Handle folders, search folders, tasks folders,
            // and contacts folder.
        }
    }
}

AttachmentInfoResponseMessageType

The AttachmentInfoResponseMessageType type is the response message for GetAttachment and CreateAttachment operations. The following two types of attachments can be found in an AttachmentInfoResponseMessageType response:

  • File attachments
  • Item attachments

The AttachmentInfoResponseMessageType object contains an Attachments property that returns an AttachmentType[]. Each attachment in the AttachmentType can be either a FileAttachmentType or an ItemAttachmentType. Type check each attachment and then cast it to the appropriate attachment type. The following code example shows how to access the attachment types.

foreach (ResponseMessageType responseMessage in rmta)
{ 
    AttachmentInfoResponseMessageType airmt = (responseMessage as AttachmentInfoResponseMessageType);
    AttachmentType[] attachments = airmt.Attachments;
    
    // Type check for item or file attachment.
    foreach (AttachmentType attachment in attachments)
    {
        if (attachment is FileAttachmentType)
        {
            FileAttachmentType fat = (attachment as FileAttachmentType);
            // TODO: Handle file attachment.
            
        }

        // Attachment is item attachment.
        else
        {
            ItemAttachmentType iat = (attachment as ItemAttachmentType);
            // TODO: Handle item attachment.
        }
    }
}

Note

File attachment content is contained in a byte[].

DeleteAttachmentResponseMessageType

The DeleteAttachmentResponseMessageType object provides the item identifier and new change key of the root item that contained the deleted attachment. Cast the ResponseMessageType as the DeleteAttachmentResponseMessageType type. On the DeleteAttachmentResponseMessageType object, the RootItemId property returns a RootItemIdType object. The RootItemIdType object provides the root item identifier and the updated change key of the item that contained the attachment.

ResolveNamesResponseMessageType

The ResolveNamesResponseMessageType object provides the results of a request to resolve ambiguous names. Cast the ResponseMessageType as the ResolveNamesResponseMessageType type. The ResolutionSet property on the ResolveNamesResponseMessageType object returns an ArrayOfResolutionType object. The ArrayOfResolutionType object has a Resolution property that returns a ResolutionType[]. The ResolutionType[] contains each of the possible resolutions for the submitted name.

ExpandDLResponseMessageType

The ExpandDLResponseMessageType object provides the results of a request to expand a distribution list. Cast the ResponseMessageType as the ExpandDLResponseMessageType type. The DLExpansion property of the ExpandDLResponseMessageType object returns an ArrayOfDLExpansionType object. The ArrayOfDLExpansionType object has a Mailbox property that returns an EmailAddressType[]. Each EmailAddressType that is returned by the Mailbox property represents a single e-mail address in the distribution list.

GetEventsResponseMessageType

The GetEventsResponseMessageType object provides a set of notifications for a pull subscription. In addition to the cast from the ResponseMessageType to GetEventsResponseMessageType, a set of casts must be performed on the BaseNotificationEventType objects that represent each notification. The following code example shows how to access the base type object for each notification item.

// Send the GetEvents request and receive the GetEvents response.
GetEventsResponseType eventsResponse = esb.GetEvents(getEventsRequest);
ArrayOfResponseMessagesType aormt = eventsResponse.ResponseMessages;
ResponseMessageType[] rmta = aormt.Items;

foreach (ResponseMessageType rmt in rmta)
{
    GetEventsResponseMessageType responseMessage = (rmt as GetEventsResponseMessageType);
    NotificationType notificaton = responseMessage.Notification;
    BaseNotificationEventType[] bneta = notificaton.Items;
    foreach (BaseNotificationEventType bnet in bneta)
    { 
        // TODO: Handle each notification.
    }
}

Important

The push notification sample that is included with the downloadable Microsoft Exchange Server 2007 Software Development Kit (SDK) contains a code example that shows how to handle the casts that are performed on each BaseNotificationEventType. To access the push notification sample, download the Microsoft Exchange Server 2007 SDK from the Microsoft Download Center, and in the \Samples\PushNotification\PushNotificationClient folder, open PushNotificationClient.cs. For more information, see Push Notification Sample Application (Exchange Web Services).

SubscribeResponseMessageType

The SubscribeResponseMessageType object provides the watermark and subscription identifier for pull subscriptions. The watermark and subscription identifier can be accessed from the Watermark and SubscriptionId properties of the SubscribeResponseMessageType object. Perform a cast on the ResponseMessageType to the SubscribeResponseMessageType to access the watermark and subscription identifier. Use the watermark and subscription identifier for the GetEvents Operation.

SendNotificationResponseMessageType

The SendNotificationResponseMessage object provides notifications for a push subscription. The PushNotificationClient.cs file includes a code example that shows how to access the notifications that are contained in a SendNotificationResponseMessage object. To access the push notification sample, download the Microsoft Exchange Server 2007 SDK from the Microsoft Download Center, and in the \Samples\PushNotification\PushNotificationClient folder, open PushNotificationClient.cs. For more information, see Push Notification Sample Application (Exchange Web Services).

SyncFolderHierarchyResponseMessageType

The SyncFolderHierarchyResponseMessageType object contains the set of changes that are made to a folder hierarchy. SyncFolderHierarchyResponseMessageType contains a Changes property that returns a SyncFolderHierarchyChangesType object. The SyncFolderHierarchyChangesType object contains an Items property that returns an object[]. The object[] contains the array of folder hierarchy changes that were made since the last synchronization, as specified by the SyncState property in the request. To access the information used to synchronize the folder hierarchy, cast each object in the object[]to either a SyncFolderHierarchyCreateOrUpdateType or a SyncFolderHierarchyDeleteType. The following code example shows how to access the changed items in a SyncFolderHierarchy response.

foreach (ResponseMessageType responseMessage in rmta)
{ 
    SyncFolderHierarchyResponseMessageType response = (responseMessage as SyncFolderHierarchyResponseMessageType);
    SyncFolderHierarchyChangesType syncFolderChanges = response.Changes;
    object[] changeTypes = syncFolderChanges.Items;
    
    foreach (object obj in changeTypes)
    {
        if (obj is SyncFolderHierarchyCreateOrUpdateType)
        {
            SyncFolderHierarchyCreateOrUpdateType change = (obj as SyncFolderHierarchyCreateOrUpdateType);
            BaseFolderType folder = change.Item;
            // TODO: Type check and cast to appropriate folder type.
            // TODO: Handle new folder or folder changes.
        }

        // Delete folder change.
        else
        {
            SyncFolderHierarchyDeleteType deleteFolder = (obj as SyncFolderHierarchyDeleteType);
            FolderIdType folderId = deleteFolder.FolderId;
            // TODO: Handle folder deletion.
        }
    }
}

SyncFolderItemsResponseMessageType

The SyncFolderItemsResponseMessageType object contains a structure that is similar to the SyncFolderHierarchyResponseMessageType object. The difference is that the SyncFolderItemsResponseMessageType object contains changes made to items in a specific folder instead of the changes made to the folder hierarchy. SyncFolderItemsResponseMessageType contains a Changes property that returns a SyncFolderItemsChangesType object. The SyncFolderItemsChangesType object contains an Items property that returns an object[]. The object[] contains the array of item changes that were made since the last synchronization, as specified by SyncState property in the request. To access the information used to synchronize the items in the folder, cast each object in the object[]to either a SyncFolderItemsCreateOrUpdateType or a SyncFolderItemsDeleteType. The following code example shows how to access the changed items in a SyncFolderItems response.

foreach (ResponseMessageType rmt in rmta)
{
    SyncFolderItemsResponseMessageType response = (rmt as SyncFolderItemsResponseMessageType);
    SyncFolderItemsChangesType syncItemsChanges = response.Changes;
    object[] changeTypes = syncItemsChanges.Items;

    foreach (object obj in changeTypes)
    {
        if (obj is SyncFolderItemsCreateOrUpdateType)
        {
            SyncFolderItemsCreateOrUpdateType change = (obj as SyncFolderItemsCreateOrUpdateType);
            ItemType item = change.Item;
            // TODO: Type check and cast to appropriate item type.
            // TODO: Handle new items or item changes.
        }

        // Delete item change.
        else
        {
            SyncFolderItemsDeleteType deleteItem = (obj as SyncFolderItemsDeleteType);
            ItemIdType itemId = deleteItem.ItemId;
            // TODO: Handle item deletion.
        }
    }
}

Accessing Availability Response Messages

The data structure in the Availability responses is different from the structure of the other response messages that are included in Exchange Web Services. The SetUserOofSettings response message is accessed by the ResponseMessage property of the SetUserOofSettingsResponse class. The GetUserOofSettings response provides a ResponseMessage property in addition to other properties that contain response information. The GetUserAvailability response contains the ResponseMessageType deeper in its object hierarchy.

GetUserAvailabilityResponseType

The GetUserAvailabilityResponseType contains response information in both the FreeBusyResponseArray and the SuggestionsResponse properties. Each of these properties contains a ResponseMessageType that provides the status for the requested data. In addition to the ResponseMessageType, both of the FreeBusyResponseArray and SuggestionsResponse properties provide response information that covers free/busy data and suggested meeting times.

GetUserOofSettingsResponse

The GetUserOofSettingsResponse returns OOF settings in addition to the response status. The response does not require any casts to access the response properties. The following code example shows how to access the response information.

GetUserOofSettingsResponse response = esb.GetUserOofSettings(request);
UserOofSettings oofSettings = response.OofSettings;
ResponseMessageType responseStatus = response.ResponseMessage;

SetUserOofSettingsResponse

The SetUserOofSettingsResponse returns only the status of the request. The ResponseMessageType properties are the only properties returned in the response.