3

信頼できるドメインに存在し、そのドメインのExchangeサーバー上のメールボックスカレンダーのコレクションを監視し、1つまたは複数の他のサーバー上の異なるメールボックスに予定を同期するために必要なアプリを構築しています。同期されるメールボックスは、このアプリケーションのユーザーによって維持される内部マッピングテーブル(sqlce)で定義されます。

私が抱えている問題は、リモートアポイントメントを追跡して、必要に応じて更新または削除できるようにする方法を見つけられないことです。リモートサーバーで予定を作成した後、ローカルExchangeサーバーでの同期フォルダーitems呼び出しによって返されるものに対応しない新しいitemidがあります。変更または削除された可能性があるため、開始時間/件名でアイテムを見つけることができません。

私の同期メソッドは以下のとおりです-これは完全に間違った方法で行っていますか、それともSyncFolderItemsメソッドを使用するためのより良い方法がありますか?

問題を回避するためにこれまでに思いついた最善のアプローチは、リモートアポイントメントのItemIDをローカルアポイントメントのプロパティに保存することですが、これでも、後にどのプロパティが維持されるかわからないため、機能するかどうかはわかりません。削除しますか?助けてください!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Exchange.WebServices.Data;
using System.Net;

namespace ProExchangeSync2012
{
    class ExchangeWebServiceMethods
    {

    public string ProExchangeSyncCalendars(string LocalMailbox
                                                ,string RemoteMailbox
                                                ,string SyncState    
                                                ,ExchangeService RemoteService
                                                ,ExchangeService LocalService
                                                )
    {
        //if SyncState is empty string set to null
        if (SyncState.ToString().Length == 0)
        { SyncState = null; }

        ExchangeService LocalExchangeService = LocalService;
        ExchangeService RemoteExchangeService = RemoteService;
        RemoteExchangeService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress,RemoteMailbox);


        //Folders and mailboxes to pass to the webservice in SyncItems call.
        Mailbox DonorMailBox = new Mailbox(LocalMailbox);
        Mailbox DestinationMailBox = new Mailbox(RemoteMailbox);
        FolderId DonorFolder = new FolderId(WellKnownFolderName.Calendar, DonorMailBox);
        FolderId DestinationFolder = new FolderId(WellKnownFolderName.Calendar, DestinationMailBox);

        //Create a ChangeCollection object and call syncfolderitems on local exchange service.
        ChangeCollection<ItemChange> ItemChanges
        = LocalExchangeService.SyncFolderItems(new FolderId(WellKnownFolderName.Calendar, DonorMailBox) //PASS IN THE MAILBOX HERE>
                                        , PropertySet.FirstClassProperties
                                        , null
                                        , 512
                                        , SyncFolderItemsScope.NormalItems
                                        , SyncState
                                        );


        //Store the SyncState
        SyncState = ItemChanges.SyncState;

        //Fetch all the required properties of the items
        //LocalService.LoadPropertiesForItems(ItemChanges, PropertySet.FirstClassProperties);

        if (ItemChanges.Count == 0)
        {
            Console.WriteLine("There are no items to synchronize.");
        }
        else
        {
            foreach (ItemChange ic in ItemChanges)
            {
                if (ic.ChangeType == ChangeType.Create)
                {
                    Appointment lappointment = Appointment.Bind(LocalExchangeService, ic.ItemId);
                    Appointment rappointment = new Appointment(RemoteExchangeService);
                    rappointment.Subject = lappointment.Subject;
                    rappointment.Start = lappointment.Start;
                    rappointment.Body = lappointment.Body;
                    rappointment.End = lappointment.End;
                    rappointment.Location = lappointment.Location;
                    rappointment.Save();

                }

                else if (ic.ChangeType == ChangeType.Update)
                {
                    //Bind to the local appointment and get the start date
                    Appointment lappointment = Appointment.Bind(LocalExchangeService, ic.ItemId);
                    DateTime StartDate = lappointment.Start;
                    ItemId ItemToUpdate = ItemIDSearch(RemoteExchangeService,StartDate,lappointment.Subject);
                    //Bind to the remote appointment using ItemToUpdate & update all the details 
                    //this is is less intensive than comparing the appointments for changes.
                    Appointment rappointment = Appointment.Bind(RemoteExchangeService, ItemToUpdate);
                    rappointment.Subject = lappointment.Subject;
                    rappointment.Start = lappointment.Start;
                    rappointment.Body = lappointment.Body;
                    rappointment.End = lappointment.End;
                    rappointment.Location = lappointment.Location;
                    rappointment.Save();

                }
                else if (ic.ChangeType == ChangeType.Delete)
                {
                    Appointment lappointment = Appointment.Bind(LocalExchangeService, ic.ItemId.UniqueId);
                    DateTime StartDate = lappointment.Start;
                    ItemId ItemToUpdate = ItemIDSearch(RemoteExchangeService, StartDate, lappointment.Subject);
                    Appointment rappointment = Appointment.Bind(RemoteExchangeService, ic.ItemId.UniqueId);
                    rappointment.Delete(DeleteMode.MoveToDeletedItems);
                }

            }
        }


        return SyncState;
    }
    //End of Sync Method

    //Below method returns a single itemid from exchange service based on start datetime of an appointment in a mailbox.
    public ItemId ItemIDSearch(ExchangeService ExchangeService, DateTime AppointmentStart, string subject)
    {
        ItemId FoundItem;
        ItemView iv = new ItemView(1000);
        iv.Traversal = ItemTraversal.Associated;

        SearchFilter.SearchFilterCollection searchFilterCollection =  new SearchFilter.SearchFilterCollection(LogicalOperator.And);
        searchFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.Subject,subject));
        searchFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.Start, AppointmentStart));

        FindItemsResults<Item> fiitems = ExchangeService.FindItems(WellKnownFolderName.Calendar, searchFilterCollection, iv);

        if (fiitems.Items.Count == 1)//if we only get one result do the work else return null
        {
            FoundItem = fiitems.Items[0].Id;
        }

        FoundItem = null;

        return FoundItem;          
    }


}
    }
4

1 に答える 1

3

したがって、Exchange Web サービスのメシアである Glen Scales からもたらされたこれらすべてに対する最終的な解決策は、同期している予定の「CleanGlobalObjectId」を、呼び出し時に返される EWS UniqueId と共に内部データベースに保存することでした。 EWS SyncFolderItems メソッド。

予定の拡張プロパティである CleanGlobalObjectId を使用すると、このプロパティの値が変更されないため、物理的に削除された場合でも、サーバー上で特定の予定を常に見つけることができました。

于 2012-08-06T11:47:27.237 に答える