更新与EWS的联系

问题描述:

我一直在努力寻找如何与EWS合作,并设法解决如何处理我想要的一切。我正在使用EWS来管理自定义数据库与Exchange服务器(2007)之间的联系。添加和删​​除作品很好,但我无法更新联系人。为了解决这个问题,我删除了联系人并重新创建了该联系人,但是当通过Outlook编辑联系人时(或者其他),问题就出现了。更新与EWS的联系

我想请点击此链接说什么:

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

,但我得到一个错误,指出只有一个属性可以更新。然后我每次更新一个属性,当我尝试更新电话号码时,我收到一个错误消息,内容如下:“名称空间中的元素'Updates'http://schemas.microsoft.com/exchange/services/2006/types'内容不完整。“

下面是代码,基本上是:

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

有谁知道为什么我得到这个错误?任何人都可以回答如何实际更新项目?我有错过的文件吗?

EWS dll的版本是15.0.516.12。

经过多次调试,我找到了答案。我不打算去探索更多的找出原因,但你不能做到这一点:

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); 

你可以,但是,只设定一个电话号码,然后在调试时更改值对于其他两个(而在一个断点)。奇怪的。

无论如何,存在一个问题 - 如果值没有改变(这就是答案,不能更新这些字典值中的一个),所以首先检查值是否改变。接下来,如果一个值是一个空字符串,则需要将其保存为空值。您还需要在尝试读取其值之前检查字典条目是否存在。

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); 
} 

要更新地址:

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); 

这,在我看来,是草率的API实现(与文档质量很差)的。

需要对项目的每个属性执行更新的事实可能是由于运行Exchange 2007的服务器导致的,但尚未得到确认。

我试用了Microsoft.Exchange.WebServices的14和15版本,结果相同。

更新

别急,还有更精彩的。该代码还显示了如何更新(或设置)标题,性别,后缀和自定义属性(用户定义的字段 - 如果您想要在Outlook中显示,则需要将用户定义的字段添加到联系人文件夹)。

这里是一个代码完整,工作片:

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); 
+0

嗨马克, 你有没有管理从EWS收到此错误信息返回到清除电子邮件地址?错误:“更改说明中的对象必须包含一个且只有一个要修改的属性。” 如果我将电子邮件地址设置为“ - ”,它可以正常工作。只要我将它设置为String.Empty或null,我就会收到错误消息。 –

+1

嗨,卡尔,据我所知你必须将它设置为空,如果你想它是空的。你不能将它设置为string.Empty。此外,只有设置电子邮件地址,如果它被发现。使用Contact.EmailAddresses.TryGetValue() - 这会返回一个布尔值。如果没有电子邮件地址,则不能将其设置为空。另一件要检查的是你所有的其他属性 - 确保它们都被正确设置(并且它们在尝试之前被发现)。您可能会错误地设置一个,并且电子邮件地址没问题。 –

您是否尝试过使用微软在their example使用的方式来更新办公地址:

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; 

这样一个新的PhysicalAddressEntry -object被创建可以解决你的问题。

(当然这不适合的电话号码。帮助)

+0

看起来它会很好地工作。在我的代码中,如果找不到地址,我会为相关的地址分配一个新的地址条目。我认为如果条目存在,你不能指定一个新的。也许当某些字段有空字符串时。我不记得确切,但应该有一个很好的理由,我没有这样做(因为它是在我的代码,如果条目不存在)。但我可能完全错误。如果您或其他人使用您的方法更新地址,请告诉我们它是否有效。 –

+0

实际上,当我使用它时,即使pysicaladress已经包含一个项目,它也可以工作。所以对我来说这很好。 – Sam

+1

感谢您的意见。 –