简体   繁体   中英

How to reply to an email using the EWS Managed API?

I have created an application that uses the EWS Managed API 2.2. This application uses pull notifications to get new emails and saves a copy of the email in a database.

Then in the application I want to get the email from database and reply to it. In order to reply to the message, I need to retrieve it from EWS using the ItemId I have stored in my database.

Of course I can create a new EmailMessage and send it but then the new email will have a different ConversationId which is not acceptable for the application scenario.

So, in order to achieve this I use the the following line of code EmailMessage.Bind(service, itemId);

For this method to work I have to instantiate the ItemId from my database but the ItemId constructor takes as parameter only the UniqueId, and creates it with null ChangeKey. If I use this ItemId (with null ChangeKey) I get the following error: Microsoft.Exchange.WebServices.Data.ServiceResponseException: The specified object was not found in the store.

I think that this is because of the null ChangeKey. Am I correct? Is there a workaround about this?

Instead of identifying a message by ItemId, use EntryID. Using EntryID, you can bind to the same email without needing ChangeKey.

Here is the definition of such property:

ExtendedPropertyDefinition EntryIDProperty = new ExtendedPropertyDefinition(0x0FFF, MapiPropertyType.Binary);

When you do your search for messages, make sure you instruct EWS to include such property in the list of retrieved items.

Here is an example to obtain EntryIDs when you invoke FindItems:

ExtendedPropertyDefinition EntryIDProperty = new ExtendedPropertyDefinition(0x0FFF, MapiPropertyType.Binary);

ItemView item_view = new ItemView(10) { PropertySet = new PropertySet(ItemSchema.Id, EntryIDProperty) };

var result = service.FindItems(WellKnownFolderName.Inbox, item_view);

foreach (var item in result.Items)
{
    byte[] entry_id = (byte[])item.ExtendedProperties.Single(x => x.PropertyDefinition == EntryIDProperty).Value;

    string entry_id_hex = ByteArrayToHexString(entry_id); //This is the entry ID that you should store
}

Use the following method to convert a EntryID to ItemID if you want to use EmailMessage.Bind:

This method accepts string EntryID.

mailbox_address is the SMTP address of the mailbox (eg test@domain.com)

'service' is the ExchangeService object.

private ItemId ConvertEntryIdToItemId(string entryid, string mailbox_address, ExchangeService service)
{
    AlternateId id = new AlternateId(IdFormat.HexEntryId, entryid, mailbox_address);

    AlternateId new_id = (AlternateId)service.ConvertId(id, IdFormat.EwsId);

    ItemId item_id = new_id.UniqueId;

    return item_id;
}

Now you can use the returned ItemId to bind your EmailMessages.

The specified object was not found in the store.

That error generally means that you don't have rights to the Mailbox your trying to access or the Item your trying to access no longer exists in the store. Eg in a pull notification application that can mean the Item that you being notified about has already been deleted or moved to another folder (in each of these case the Item will be assigned a new Id). If you also listing to Move event you should be able to see the corresponding move event which will have the OldItemId that correlates the newMailEvent notification.

The Change Key only matters when your updating an Item so in the case the error you getting on Bind means that Item your trying doesn't exist (or has been moved) or you don't have rights to access it binding with just the UniqueId is perfectly okay see also https://msdn.microsoft.com/en-us/library/office/dn605828(v=exchg.150).aspx

Cheers Glen

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM