Contact update with EWS

I struggled to figure out how to work with EWS, and I managed to figure out how to do everything I wanted. I use EWS to manage contacts between a custom database and an Exchange server (2007). Adding and removing jobs is just fine, but I can’t update the contact. To get around this, I deleted the contact and recreated it, but the problem occurs when the contact is edited through Outlook (or something else).

I tried to keep track of what this link says:

http://msdn.microsoft.com/en-us/library/exchange/ee693002(v=exchg.80).aspx

but I get an error that only one property can be updated. Then I update each property one at a time, and as soon as I try to update the phone number, I get an error: "Updates" element in the namespace 'http://schemas.microsoft.com/exchange/services/2006/types' has incomplete content.

Here is the code, basically:

ItemId itemId = contactToUpdate.Id; Contact updateContact = Contact.Bind(service, itemId); updateContact.PhoneNumbers[PhoneNumberKey.HomePhone] = customContact.HomeTelephone; updateContact.Update(ConflictResolutionMode.AlwaysOverwrite); 

Does anyone know why I am getting this error? Can anyone answer how to really update an item? Is there any documentation I missed?

The EWS DLL version is 15.0.516.12.

+4
source share
2 answers

I found the answer to this after much debugging. I am not going to research more to find out why, but you cannot do this:

 updateContact = Contact.Bind(service, itemId); updateContact.PhoneNumbers[PhoneNumberKey.HomePhone] = customContact.HomePhone; updateContact.PhoneNumbers[PhoneNumberKey.MobilePhone] = customContact.MobilePhone; updateContact.PhoneNumbers[PhoneNumberKey.BusinessPhone] = customContact.BusinessPhone; updateContact.Update(ConflictResolutionMode.AlwaysOverwrite); 

However, you can only set one phone number and then change the values ​​for the other two during debugging (while at the breakpoint). Weird

In any case, there is a problem: you cannot update one of these dictionary values ​​if the value does not change (this is a short answer), so first check to see if the value has changed. Then, if the value is an empty string, you should rather save it as null. You also need to check if a dictionary entry exists before trying to read its meaning.

 string number; bool numberFound; numberFound = updateContact.PhoneNumbers.TryGetValue(PhoneNumberKey.HomePhone, out number); if ((numberFound && number != customContact.HomePhone) || (!numberFound && !string.IsNullOrEmpty(customContact.HomePhone))) { updateContact = Contact.Bind(service, itemId); updateContact.PhoneNumbers[PhoneNumberKey.HomePhone] = customContact.HomePhone == "" ? null : customContact.HomePhone; updateContact.Update(ConflictResolutionMode.AlwaysOverwrite); } 

To update the address:

 updateContact = Contact.Bind(service, itemId); updateContact.PhysicalAddresses[PhysicalAddressKey.Home].Street = customContact.Street == "" ? null : customContact.Street; updateContact.PhysicalAddresses[PhysicalAddressKey.Home].State = customContact.Suburb == "" ? null : customContact.Suburb; updateContact.PhysicalAddresses[PhysicalAddressKey.Home].City = customContact.City == "" ? null : customContact.City; updateContact.PhysicalAddresses[PhysicalAddressKey.Home].CountryOrRegion = customContact.Country == "" ? null : customContact.Country; updateContact.PhysicalAddresses[PhysicalAddressKey.Home].PostalCode = customContact.AreaCode == "" ? null : customContact.AreaCode; updateContact.Update(ConflictResolutionMode.AlwaysOverwrite); 

This, in my opinion, is a careless implementation of the API (and poor documentation).

The fact that an update must be performed for each item property may be related to the Exchange 2007 server, but this has not yet been confirmed.

I tried both with versions 14 and 15 Microsoft.Exchange.WebServices with the same results.

Update

But wait, there still.

I post a lot of code to illustrate how to update different phone numbers, addresses, etc. The code also shows how to update (or set) the header, gender, suffix and custom property (user field, which if you want to appear in Outlook, you need to add the field specified by the user to the contacts folder).

Here is the full working code:

 Contact updateContact = Contact.Bind(service, itemId); updateContact.GivenName = customContact.Name; updateContact.Surname = customContact.Surname; EmailAddress emailAddress; bool emailAddressFound; emailAddressFound = updateContact.EmailAddresses.TryGetValue(EmailAddressKey.EmailAddress1, out emailAddress); if (emailAddressFound && emailAddress.Address != customContact.Email) { emailAddress.Address = customContact.Email == "" ? null : customContact.Email; } else if (!emailAddressFound && !string.IsNullOrEmpty(customContact.Email)) { updateContact.EmailAddresses[EmailAddressKey.EmailAddress1] = customContact.Email; } updateContact.Initials = customContact.Initials; string number; bool numberFound; numberFound = updateContact.PhoneNumbers.TryGetValue(PhoneNumberKey.HomePhone, out number); if ((numberFound && number != customContact.HomePhone) || (!numberFound && !string.IsNullOrEmpty(customContact.HomePhone))) { updateContact.PhoneNumbers[PhoneNumberKey.HomePhone] = customContact.HomePhone == "" ? null : customContact.HomePhone; } numberFound = updateContact.PhoneNumbers.TryGetValue(PhoneNumberKey.MobilePhone, out number); if ((numberFound && number != customContact.CellPhone) || (!numberFound && !string.IsNullOrEmpty(customContact.CellPhone))) { updateContact.PhoneNumbers[PhoneNumberKey.MobilePhone] = customContact.CellPhone == "" ? null : customContact.CellPhone; } numberFound = updateContact.PhoneNumbers.TryGetValue(PhoneNumberKey.BusinessPhone, out number); if ((numberFound && number != customContact.WorkPhone) || (!numberFound && !string.IsNullOrEmpty(customContact.WorkPhone))) { updateContact.PhoneNumbers[PhoneNumberKey.BusinessPhone] = customContact.WorkPhone == "" ? null : customContact.WorkPhone; } PhysicalAddressEntry phsicalAddress; bool phsicalAddressFound; int phsicalAddressLength = (customContact.Street + customContact.Suburb + customContact.City + customContact.Country + customContact.AreaCode).Length; phsicalAddressFound = updateContact.PhysicalAddresses.TryGetValue(PhysicalAddressKey.Home, out phsicalAddress); if (phsicalAddressFound) { updateContact.PhysicalAddresses[PhysicalAddressKey.Home].Street = customContact.Street == "" ? null : customContact.Street; updateContact.PhysicalAddresses[PhysicalAddressKey.Home].State = customContact.Suburb == "" ? null : customContact.Suburb; updateContact.PhysicalAddresses[PhysicalAddressKey.Home].City = customContact.City == "" ? null : customContact.City; updateContact.PhysicalAddresses[PhysicalAddressKey.Home].CountryOrRegion = customContact.Country == "" ? null : customContact.Country; updateContact.PhysicalAddresses[PhysicalAddressKey.Home].PostalCode = customContact.AreaCode == "" ? null : customContact.AreaCode; } else if (!phsicalAddressFound && phsicalAddressLength > 0) { updateContact.PhysicalAddresses[PhysicalAddressKey.Home] = homeAddress; } phsicalAddressLength = (customContact.BusinessStreet + customContact.BusinessSuburb + customContact.BusinessCity + customContact.BusinessCountry + customContact.BusinessAreaCode).Length; phsicalAddressFound = updateContact.PhysicalAddresses.TryGetValue(PhysicalAddressKey.Business, out phsicalAddress); if (phsicalAddressFound) { updateContact.PhysicalAddresses[PhysicalAddressKey.Business].Street = customContact.BusinessStreet == "" ? null : customContact.BusinessStreet; updateContact.PhysicalAddresses[PhysicalAddressKey.Business].State = customContact.BusinessSuburb == "" ? null : customContact.BusinessSuburb; updateContact.PhysicalAddresses[PhysicalAddressKey.Business].City = customContact.BusinessCity == "" ? null : customContact.BusinessCity; updateContact.PhysicalAddresses[PhysicalAddressKey.Business].CountryOrRegion = customContact.BusinessCountry == "" ? null : customContact.BusinessCountry; updateContact.PhysicalAddresses[PhysicalAddressKey.Business].PostalCode = customContact.BusinessAreaCode == "" ? null : customContact.BusinessAreaCode; } else if (!phsicalAddressFound && phsicalAddressLength > 0) { updateContact.PhysicalAddresses[PhysicalAddressKey.Business] = businessAddress; } updateContact.Birthday = customContact.Birthdate; updateContact.WeddingAnniversary = customContact.MaritalStatusDate; // Extended properties ------------------------------------------------------------- ExtendedPropertyDefinition extendedPropertyDefinition; // Gender if (!string.IsNullOrEmpty(customContact.Gender)) { extendedPropertyDefinition = new ExtendedPropertyDefinition(0x3a4d, MapiPropertyType.Short); switch (customContact.Gender) { case "Male": updateContact.SetExtendedProperty(extendedPropertyDefinition, 2); break; case "Female": updateContact.SetExtendedProperty(extendedPropertyDefinition, 1); break; default: updateContact.SetExtendedProperty(extendedPropertyDefinition, 3); break; } } // Title if (!string.IsNullOrEmpty(customContact.Title)) { extendedPropertyDefinition = new ExtendedPropertyDefinition(0x3a45, MapiPropertyType.String); updateContact.SetExtendedProperty(extendedPropertyDefinition, customContact.Title); } // Suffix if (!string.IsNullOrEmpty(customContact.Suffix)) { extendedPropertyDefinition = new ExtendedPropertyDefinition(0x3a05, MapiPropertyType.String); updateContact.SetExtendedProperty(extendedPropertyDefinition, customContact.Suffix); } // Custom property extendedPropertyDefinition = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "customProperty", MapiPropertyType.String); updateContact.SetExtendedProperty(extendedPropertyDefinition, customContact.CustomProperty); // File the contact updateContact.Subject = customContact.Name + " " + customContact.Surname; updateContact.DisplayName = customContact.Name + " " + customContact.Surname; updateContact.Update(ConflictResolutionMode.AlwaysOverwrite); 
+7
source

You tried to use the way Microsoft uses in its example to update a business address:

 PhysicalAddressEntry PABusinessEntry = new PhysicalAddressEntry(); PABusinessEntry.Street = "4567 Contoso Way"; PABusinessEntry.City = "Redmond"; PABusinessEntry.State = "OH"; PABusinessEntry.PostalCode = "33333"; PABusinessEntry.CountryOrRegion = "United States of America"; contact.PhysicalAddresses[PhysicalAddressKey.Business] = PABusinessEntry; 

This creates a new PhysicalAddressEntry object that can solve your problem.

(Of course, this does not help for phone numbers.)

0
source

Source: https://habr.com/ru/post/1447243/


All Articles