EWS Managed Api - 仅检索一次日历项目
EWS Managed Api - Retrieve calendar items only once
我有一个 windows 服务可以从 Exchange 中读取日历项目并将它们存储在我的应用程序的数据库中,供每个用户使用。
现在我想知道将 Exchange 上的项目标记为在存储后不在下一个服务 运行 中检索的最佳方法是什么?
我尝试将扩展的 属性 添加到日历项并设置它的值,然后每次都根据它的值进行搜索:
DateTime startDate = DateTime.Now;
DateTime endDate = startDate.AddDays(60);
const int NUM_APPTS = 60;
// Set the start and end time and number of appointments to retrieve.
CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS);
Guid myPropertyId = new Guid("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}");
ExtendedPropertyDefinition myExtendedProperty = new ExtendedPropertyDefinition(myPropertyId, "SyncFlag", MapiPropertyType.Boolean);
// Limit the properties returned to the appointment's subject, start time, end time and the extended property.
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Location, myExtendedProperty);
// Retrieve a collection of appointments by using the calendar view.
List<SearchFilter> searchFilterCollection = new List<SearchFilter>();
searchFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.Start, DateTime.Now));
searchFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.End, DateTime.Now.AddDays(60)));
searchFilterCollection.Add(new SearchFilter.IsNotEqualTo(myExtendedProperty, true)); //Do not fetch already marked calendar items
SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, searchFilterCollection);
FindItemsResults<Item> appointments = service.FindItems(WellKnownFolderName.Calendar, searchFilter, cView);
使用此代码搜索日历项会引发此异常:
Restrictions and sort order may not be specified for a CalendarView.
我也不确定这是否是最好的方法。有什么想法吗?
谢谢
一种方法是使用 SyncFolderItems
方法。它将 return 自上次调用以来更改的项目。您所要做的就是在每次调用之间保存同步 "cookie"。
您还应过滤掉自上次通话后创建的约会项目。
下面的代码片段应该可以解决问题。
static private void GetChangedItems()
{
// Path to cookie
string syncStateFileName = @"c:\temp\ewssyncstate.txt";
try
{
var service = GetServiceAP();
bool moreChangesAvailable = false;
do
{
string syncState = null;
if (File.Exists(syncStateFileName))
{
// Read cookie
syncState = File.ReadAllText(syncStateFileName);
}
ChangeCollection<ItemChange> icc = service.SyncFolderItems(new FolderId(WellKnownFolderName.Calendar), PropertySet.FirstClassProperties, null, 10, SyncFolderItemsScope.NormalItems, syncState);
if (icc.Count == 0)
{
Console.WriteLine("There are no item changes to synchronize.");
}
else
{
syncState = icc.SyncState;
// Save cookie
File.WriteAllText(syncStateFileName, syncState);
moreChangesAvailable = icc.MoreChangesAvailable;
// Only get appointments that were created since last call
var createdItems = icc
.Where(i => i.ChangeType == ChangeType.Create)
.Select(i => i.Item as Appointment)
;
if (createdItems.Any())
{
service.LoadPropertiesForItems(createdItems, PropertySet.FirstClassProperties);
foreach (Appointment appointment in createdItems)
{
Console.WriteLine(appointment.Subject);
}
}
}
}
while (moreChangesAvailable);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
我有一个 windows 服务可以从 Exchange 中读取日历项目并将它们存储在我的应用程序的数据库中,供每个用户使用。 现在我想知道将 Exchange 上的项目标记为在存储后不在下一个服务 运行 中检索的最佳方法是什么?
我尝试将扩展的 属性 添加到日历项并设置它的值,然后每次都根据它的值进行搜索:
DateTime startDate = DateTime.Now;
DateTime endDate = startDate.AddDays(60);
const int NUM_APPTS = 60;
// Set the start and end time and number of appointments to retrieve.
CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS);
Guid myPropertyId = new Guid("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}");
ExtendedPropertyDefinition myExtendedProperty = new ExtendedPropertyDefinition(myPropertyId, "SyncFlag", MapiPropertyType.Boolean);
// Limit the properties returned to the appointment's subject, start time, end time and the extended property.
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Location, myExtendedProperty);
// Retrieve a collection of appointments by using the calendar view.
List<SearchFilter> searchFilterCollection = new List<SearchFilter>();
searchFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.Start, DateTime.Now));
searchFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.End, DateTime.Now.AddDays(60)));
searchFilterCollection.Add(new SearchFilter.IsNotEqualTo(myExtendedProperty, true)); //Do not fetch already marked calendar items
SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, searchFilterCollection);
FindItemsResults<Item> appointments = service.FindItems(WellKnownFolderName.Calendar, searchFilter, cView);
使用此代码搜索日历项会引发此异常:
Restrictions and sort order may not be specified for a CalendarView.
我也不确定这是否是最好的方法。有什么想法吗?
谢谢
一种方法是使用 SyncFolderItems
方法。它将 return 自上次调用以来更改的项目。您所要做的就是在每次调用之间保存同步 "cookie"。
您还应过滤掉自上次通话后创建的约会项目。
下面的代码片段应该可以解决问题。
static private void GetChangedItems()
{
// Path to cookie
string syncStateFileName = @"c:\temp\ewssyncstate.txt";
try
{
var service = GetServiceAP();
bool moreChangesAvailable = false;
do
{
string syncState = null;
if (File.Exists(syncStateFileName))
{
// Read cookie
syncState = File.ReadAllText(syncStateFileName);
}
ChangeCollection<ItemChange> icc = service.SyncFolderItems(new FolderId(WellKnownFolderName.Calendar), PropertySet.FirstClassProperties, null, 10, SyncFolderItemsScope.NormalItems, syncState);
if (icc.Count == 0)
{
Console.WriteLine("There are no item changes to synchronize.");
}
else
{
syncState = icc.SyncState;
// Save cookie
File.WriteAllText(syncStateFileName, syncState);
moreChangesAvailable = icc.MoreChangesAvailable;
// Only get appointments that were created since last call
var createdItems = icc
.Where(i => i.ChangeType == ChangeType.Create)
.Select(i => i.Item as Appointment)
;
if (createdItems.Any())
{
service.LoadPropertiesForItems(createdItems, PropertySet.FirstClassProperties);
foreach (Appointment appointment in createdItems)
{
Console.WriteLine(appointment.Subject);
}
}
}
}
while (moreChangesAvailable);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}