2012-11-20 39 views
4

我一直在努力尋找如何與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。

回答

7

經過多次調試,我找到了答案。我不打算去探索更多的找出原因,但你不能做到這一點:

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() - 這會返回一個布爾值。如果沒有電子郵件地址,則不能將其設置爲空。另一件要檢查的是你所有的其他屬性 - 確保它們都被正確設置(並且它們在嘗試之前被發現)。您可能會錯誤地設置一個,並且電子郵件地址沒問題。 –

0

您是否嘗試過使用微軟在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

感謝您的意見。 –