4

我一直在努力寻找如何与 EWS 合作,并设法弄清楚如何做几乎所有我想做的事情。我正在使用 EWS 管理自定义数据库和 Exchange 服务器 (2007) 之间的联系人。添加和删​​除工作正常,但我无法更新联系人。为了解决这个问题,我删除了联系人并重新创建了它,但是当通过 Outlook(或其他任何方式)编辑联系人时,问题就出现了。

我试图按照此链接所说的内容进行操作:

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

但我收到一条错误消息,说只能更新一个属性。然后我一次更新每个属性,一旦我尝试更新电话号码,我就会收到一条错误消息:“命名空间'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。

4

2 回答 2

9

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

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

但是,您可以只设置一个电话号码,然后在调试时(在断点上)更改另外两个的值。奇怪的。

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

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);
于 2012-11-21T14:08:53.243 回答
0

您是否尝试过使用 Microsoft 在他们的示例中使用的方式来更新公司地址:

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,它可能会解决您的问题。

(当然这对电话号码没有帮助。)

于 2013-11-25T09:51:17.950 回答