使用 EWS 列出所有可用的扩展属性

List all available extended properties using EWS

我正在尝试找到一种方法来使用 EWS 列出一组日历项目的所有扩展属性。

问题是我设法在网上找到的所有示例都要求我提前知道这些扩展属性是什么。这是 official MSDN example.

不知道扩展属性的ID或名称怎么办?或者如果我根本不知道是否存在任何扩展属性?

我尝试了以下代码,但它 returns 是一个例外...

            var calendarItems = service.FindAppointments(WellKnownFolderName.Calendar, view);
            var propertySet = new PropertySet(AppointmentSchema.ExtendedProperties);
            service.LoadPropertiesForItems(calendarItems, propertySet);

例外情况:

Microsoft.Exchange.WebServices.Data.ServiceResponseException: The request failed schema validation: The required attribute 'FieldURI' is missing.

EWS 中没有调用来获取所有扩展属性。扩展属性背后的想法是应用程序使用它们来存储特定于应用程序的数据,因此只有该应用程序需要知道其属性的细节。

扩展 MAPI 可以发现此信息。 https://github.com/stephenegriffin/mfcmapi 有大量用于不同任务的示例代码,包括迭代命名属性。

我看起来也很相似,只是做了一种逆向工程。由于扩展 属性 是 Id(整数)和我们无法知道的数据类型的组合,因为它们没有记录在任何 MSDN 上。因此,将 1 迭代到某个巨大的数字,例如字符串类型 属性 的 15000 并找到可以成功加载的数字 - 这是最棘手的部分,我们可以通过将 try-catch 绑定到扩展 属性.然后你可以得到所需的。 希望对您有所帮助。

  List<int> allStringIds = new List<int>();
for (int i = 0; i <= 15000; i++)
{
    allStringIds.Add(i);
}

ParallelOptions options = new ParallelOptions
{
    MaxDegreeOfParallelism = 200,
    CancellationToken = CancellationToken.None,
};

Parallel.For(0, allStringIds.Count, options, index =>
{
    try
    {
     ExtendedPropertyDefinition extendedPropertyDefinition = new ExtendedPropertyDefinition(index,
                   MapiPropertyType.String);
     latestMessage = EmailMessage.Bind(service, item.Id.UniqueId,
     new PropertySet(BasePropertySet.FirstClassProperties, extendedPropertyDefinition));
     _logger.Write("Supported string property id=" + index);
     supportedListId.TryAdd(index, index);
 }
 catch(Exception ex)
 {

 }
});

 foreach (var a in supportedListId)
 {
  ExtendedPropertyDefinition extendedPropertyDefinition = new ExtendedPropertyDefinition(a.Key,
  MapiPropertyType.String);
  allExtendedPropertyDefinitions.Add(extendedPropertyDefinition);
 }
 latestMessage = EmailMessage.Bind(service, item.Id.UniqueId,
 new PropertySet(BasePropertySet.FirstClassProperties, allExtendedPropertyDefinitions));
 
 foreach (var extendedProperty in latestMessage.ExtendedProperties)
 {
 if (extendedProperty.PropertyDefinition != null && extendedProperty.PropertyDefinition.Tag != null)
 {
  if (extendedProperty.Value != null)
  {
     _logger.Write($"OMG... extendedProperty id={extendedProperty.PropertyDefinition.Id}," +
         $" name={ extendedProperty.PropertyDefinition.Name}, value={extendedProperty.Value}");
    }
   }
}