我目前正在研究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中打开apointment时执行。但由于自定义字段不在“此项中”,因此.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加载项中检索值?也许我可以检索该值并将自定义字段添加到项目中并使用值?
感谢。
答案 0 :(得分:7)
无法使用UserProperties访问EWS创建的扩展属性。但是可以使用PropertyAccessor进行访问。
outlookItem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/yourProp")
答案 1 :(得分: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;