【问题标题】:Creating extended property using EWS and access it from Outlook Add-in使用 EWS 创建扩展属性并从 Outlook 加载项访问它
【发布时间】:2011-08-26 04:06:30
【问题描述】:

我目前正在开发 EWS,以便将我们的公司应用程序与 Exchange 2010 进行一些集成。我正在使用 EWS 创建对 Exchange 2010 的预约,它工作正常;但最近我尝试在创建约会时添加一些自定义/扩展属性,下面是我添加扩展属性的代码。

Dim customField As New ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "MyCustomField", MapiPropertyType.String)

appointment.SetExtendedProperty(customField, "CustomFieldValue")

以上代码能够为约会创建自定义字段。

现在这是我的问题。当我在 Outlook 中打开我创建的约会并转到“开发人员 > 设计此表单”,然后转到“所有字段”选项卡时,我只看到我在“文件夹中的用户定义字段”中创建的自定义字段,但在"此项目中的用户定义字段"。

当用户在 Outlook 中打开约会时,我还制作了一个 Outlook 插件来响应我使用 EWS 创建的自定义字段,当我尝试查找自定义字段时,找不到自定义字段,因为自定义字段是在“文件夹中的自定义字段”中创建的,而不是在“此项中的自定义字段”中创建的。

这是 Outlook 加载项中的代码,将在用户在 Outlook 中打开一个点时执行。但是因为自定义字段不在“in this item”中,所以.Find()返回Nothing。

Dim appt As Outlook.AppointmentItem
appt = TryCast(inspector.CurrentItem, Outlook.AppointmentItem)
If appt.UserProperties.Find("MyCustomField") Is Nothing Then
    'Some action
Else
    'Some action
End If

我想要实现的是使用 EWS 创建带有自定义字段(扩展属性)的约会,然后当用户在 Outlook 中打开约会时读取 Outlook 插件中的自定义字段(扩展属性)。

编辑:

我使用 EWS 分配给自定义字段的值显示在“文件夹中的用户定义字段”中。如何从 Outlook 加载项中检索值?也许我可以检索值并将自定义字段添加到项目和值?

谢谢。

【问题讨论】:

    标签: delphi exchange-server outlook-addin extended-properties user-defined-fields


    【解决方案1】:

    我将此作为显示一些实际 (Delphi) 代码的另一个答案发布,因为第一个答案中缺少该代码。
    AAppointmentItem 是一个 OLEVariant

    const
       GUID_PS_PUBLIC_STRINGS = '{00020329-0000-0000-C000-000000000046}';
       cPublicStringNameSpace = 'http://schemas.microsoft.com/mapi/string/' + GUID_PS_PUBLIC_STRINGS + '/';
    
    var
       lPropertyAccessor: OleVariant;
       lSchemaName, lValue: String;
    
    begin   
       // Use the PropertyAccessor because Outlook UserProperties() can't access the extended properties created by EWS 
       // Use the 'string subnamespace of the MAPI namespace' (http://msdn.microsoft.com/en-us/library/office/ff868915.aspx)
       // with the PS_PUBLIC_STRINGS GUID from http://msdn.microsoft.com/en-us/library/bb905283%28v=office.12%29.aspx
       lPropertyAccessor := AAppointmentItem.PropertyAccessor;
       lSchemaName := cPublicStringNameSpace + PROPERTY_TIMETELLID;  // Name constants defined elsewhere
       try
          lSchemaName := cPublicStringNameSpace + PROPERTY_TIMETELLID;
          lValue := lPropertyAccessor.GetProperty(lSchemaName);
          lEvent.CustSyncTTID := StrToInt(lValue);
       except
       end;
       try
          lSchemaName := cPublicStringNameSpace + PROPERTY_TIMETELLSYNCTIME;
          lValue := lPropertyAccessor.GetProperty(lSchemaName);
          lEvent.CustSyncDate := UTCString2LocalDateTime(lValue);
       except
       end;
       try
          lSchemaName := cPublicStringNameSpace + PROPERTY_TIMETELLSYNCID;
          lValue := lPropertyAccessor.GetProperty(lSchemaName);
          lEvent.CustSyncEntryID := lValue;
       except
       end;
    

    请注意许多尝试例外,因为我们正在进行后期绑定; “早”会更好 (http://blog.depauptits.nl/2012/04/safely-accessing-named-properties-in.html)

    此外,我们正在检索多个用户属性,因此 GetProperties() 实际上更好。

    FWIW,这是使用 UserProperties 的旧代码(lProperty 是 OLEVariant)

    lProperty := AAppointmentItem.UserProperties.Find(PROPERTY_TIMETELLID);
    if IDispatch(lProperty) <> nil then
      lEvent.CustSyncTTID :=  lProperty.Value;
    lProperty := AAppointmentItem.UserProperties.Find(PROPERTY_TIMETELLSYNCTIME);
    if IDispatch(lProperty) <> nil then
      lEvent.CustSyncDate :=  lProperty.Value;
    lProperty := AAppointmentItem.UserProperties.Find(PROPERTY_TIMETELLSYNCID);
    if IDispatch(lProperty) <> nil then
      lEvent.CustSyncEntryID := lProperty.Value;            
    

    [2013-6-10 编辑添加]

    下面是修改后的代码,使用 GetProperties (as MS recommends) 一次处理所有三个属性:

    lPropertyAccessor := AAppointmentItem.PropertyAccessor;
    lSchemas := VarArrayOf([cPublicStringNameSpace + PROPERTY_TIMETELLID,
                            cPublicStringNameSpace + PROPERTY_TIMETELLSYNCTIME,
                            cPublicStringNameSpace + PROPERTY_TIMETELLSYNCID]);
    try
      lValues := lPropertyAccessor.GetProperties(lSchemas);
      if VarType(lValues[0]) <> varError then
         lEvent.CustSyncTTID := lValues[0];
      if VarType(lValues[1]) <> varError then
      begin
         lDT := lValues[1];
         lDT := TTimeZone.Local.ToLocalTime(lDT);
         lEvent.CustSyncDate := lDT;
      end;
      if VarType(lValues[2]) <> varError then
        lEvent.CustSyncEntryID := lValues[2];
    except
    end;
    

    【讨论】:

    • 只是出于好奇,为什么您总是将自定义属性设置为字符串,并在阅读后将它们转换为适当的格式(日期时间和 int)?设置属性时使用正确的类型会不会更容易?
    • 你是对的,这没有必要。将 lValue 更改为变体。
    【解决方案2】:

    答案在这里: http://social.technet.microsoft.com/Forums/en-US/exchangesvrdevelopment/thread/2a98b4ab-0fbc-4863-8303-48711a18a050

    无法访问 EWS 使用 UserProperties 创建的扩展属性。但可以使用 PropertyAccessor 访问。

    outlookItem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/yourProp")
    

    【讨论】:

    • 请您解释一下这个答案如何?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-03
    • 2014-12-23
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    相关资源
    最近更新 更多