none
Exchange Web Service - error while moving mail to other folder RRS feed

  • Question

  • Getting below error.  Some time working fine some time error - while move mail to other folder

    Microsoft.Exchange.WebServices.Data.ServiceResponseException: The specified object was not found in the store.
       at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary()
       at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
       at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalMoveItems(IEnumerable`1 itemIds, FolderId destinationFolderId, Nullable`1 returnNewItemIds, ServiceErrorHandling errorHandling)
       at Microsoft.Exchange.WebServices.Data.ExchangeService.MoveItem(ItemId itemId, FolderId destinationFolderId)
       at Microsoft.Exchange.WebServices.Data.Item.Move(FolderId destinationFolderId)
       at ExchangeAutoReplyService.Business.ExchangeAutoReply.MoveToSuspectAutoReplyFolder(ExchangeService service))

    Getting below error. EmailMessage current = EmailMessage.Bind(service, id); - while binding

    Some time works fine some time throws error as follows :

    Microsoft.Exchange.WebServices.Data.ServiceResponseException: The specified object was not found in the store.
       at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary()
       at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
       at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalBindToItems(IEnumerable`1 itemIds, PropertySet propertySet, ServiceErrorHandling errorHandling)
       at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToItem(ItemId itemId, PropertySet propertySet)
       at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToItem[TItem](ItemId itemId, PropertySet propertySet)
       at Microsoft.Exchange.WebServices.Data.EmailMessage.Bind(ExchangeService service, ItemId id)
       at ExchangeAutoReplyService.Business.ExchangeAutoReply.AutoReplyToSender(ExchangeService service, String mailboxEmailId))


    Jagdish


    Wednesday, December 4, 2013 9:20 AM

Answers

  • I got the Answer 

    Threading with Mutex (Mutual exclusion):

    When two or more threads need to access a shared resource at the same time, the system needs a synchronization mechanism to ensure that only one thread at a time uses the resource. Mutex is a synchronization primitive that grants exclusive access to the shared resource to only one thread. If a thread acquires a mutex, the second thread that wants to acquire that mutex is suspended until the first thread releases the mutex.

    Steps:

    • Instantiating a new Mutex object that's accessible from each thread.
    • Wrapping whatever code you want to be executed in the critical section with that object's WaitOne() and ReleaseMutex() methods in each thread

    Implementation:

    • Add class SingleGlobalInstance to your project

    1. class SingleGlobalInstance : IDisposable
    2. {
    3.     public bool hasHandle = false;
    4.     Mutex mutex;
    5.     private void InitMutex()
    6.     {
    7.         string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
    8.         string mutexId = string.Format("Global\\{{{0}}}", appGuid);
    9.         mutex = new Mutex(false, mutexId);
    10.         var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
    11.         var securitySettings = new MutexSecurity();
    12.         securitySettings.AddAccessRule(allowEveryoneRule);
    13.         mutex.SetAccessControl(securitySettings);
    14.     }
    15.     public SingleGlobalInstance(int TimeOut)
    16.     {
    17.         InitMutex();
    18.         try
    19.         {
    20.             if(TimeOut <= 0)
    21.                 hasHandle = mutex.WaitOne(Timeout.Infinite, false);
    22.             else
    23.                 hasHandle = mutex.WaitOne(TimeOut, false);
    24.             if (hasHandle == false)
    25.                 throw new TimeoutException("Timeout waiting for exclusive access on SingleInstance");
    26.         }
    27.         catch (AbandonedMutexException)
    28.         {
    29.             hasHandle = true;
    30.         }
    31.     }
    32.     public void Dispose()
    33.     {
    34.         if (mutex != null)
    35.         {
    36.             if (hasHandle)
    37.                 mutex.ReleaseMutex();
    38.             mutex.Dispose();
    39.         }
    40.     }
    41. }
      • Add following condition to check whether thread is already running

    using (new SingleGlobalInstance(1000))

    {

       //code which should be executed in single thread

     }

    Regards,

    Jagdish Kotian


    Jagdish

    • Marked as answer by Jagdish Kotian Tuesday, December 24, 2013 8:39 AM
    Tuesday, December 24, 2013 8:39 AM

All replies

  • Where are the ItemId's coming from ?

    are you using notifications ?

    if so is it possible that another client (or Mailbox Rule)has moved or deleted the Item your trying to access.

    If you save the ItemId out that your getting an error with can you then use something like the EWSEditor http://ewseditor.codeplex.com/ to bind to the Item ?

    Cheers
    Glen

    Thursday, December 5, 2013 5:16 AM
  • Hi Glen,

    Thanks for the reply.

    Our requirement is :

    1. We have developed windows service to read inbox via EWS(Exchagne Web Srvice (https)).

    2. Windows service run in 5 second interval

    3. loops through the inbox to check incoming mails code as below


    ExchangeService service = new ExchangeService();

    //Passing credential
    service.Credentials = new NetworkCredential(userName,passwoed,domain);

    //Passing EWS url - https://
    service.Url = new Uri(EwsHttpsUrl);

    //for SSL
    service.AutodiscoverUrl(mailboxUserwiseCredentials[0].ToString());
    ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) 

    => true;


    FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, new ItemView(10));


    //loop through each mail in current mailbox
    for (int i = 0; i < findResults.Items.Count; i++)
    {

    ItemId id = (ItemId)findResults.Items[i].Id;

    EmailMessage message = EmailMessage.Bind(service, id); 

    //Glen : while Bind() throwing error as below.
    //sometime this works fine without any error 

    Scenario: when there is multiple mails in inbox it loops through  and error

    message.Load();

    .....

    Some time works fine some time throws error as follows :

    Microsoft.Exchange.WebServices.Data.ServiceResponseException: The specified object was not found in the 

    store.
       at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary()
       at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
       at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalBindToItems(IEnumerable`1 itemIds, 

    PropertySet propertySet, ServiceErrorHandling errorHandling)
       at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToItem(ItemId itemId, PropertySet 

    propertySet)
       at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToItem[TItem](ItemId itemId, PropertySet 

    propertySet)
       at Microsoft.Exchange.WebServices.Data.EmailMessage.Bind(ExchangeService service, ItemId id)
       at ExchangeAutoReplyService.Business.ExchangeAutoReply.AutoReplyToSender(ExchangeService service, 

    String mailboxEmailId))

    =================================================================
    Other Issue

    Also we are getting error while moveing mails from inbox to other folder which we have crated eg : Done - folder

    Scenario: 
    We are looping through inbox after reading mail one by one we are moving to "Done" folder which is created by us.

    Code  is :

    FindItemsResults<Item> findResultsForMove = null;

    findResultsForMove = service.FindItems(WellKnownFolderName.Inbox, new ItemView(50));

    FindFoldersResults findResultsFindFolder = service.FindFolders(WellKnownFolderName.Inbox, new 

    FolderView(int.MaxValue));


    older folderToMove = null;
    string folderNameToMove = "Done" //folder crated by us

     foreach (Folder folder in findResultsFindFolder)
    {
    if (folder.DisplayName == folderNameToMove.ToString().Trim())
    {
    folderToMove = folder;  //searching for the Done folder
    }
    }

    //once folder "Done" found then moves first item[0] to move folder
    //working fine but error some time
     
    findResultsForMove.Items[0].Move(folderToMove.Id);



    Here also same - Some time works fine without any error some time throws error as follows :

    Microsoft.Exchange.WebServices.Data.ServiceResponseException: The specified object was not found in the 

    store.
       at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary()
       at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
       at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalBindToItems(IEnumerable`1 itemIds, 

    PropertySet propertySet, ServiceErrorHandling errorHandling)
       at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToItem(ItemId itemId, PropertySet 

    propertySet)
       at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToItem[TItem](ItemId itemId, PropertySet 

    propertySet)
       at Microsoft.Exchange.WebServices.Data.EmailMessage.Bind(ExchangeService service, ItemId id)
       at ExchangeAutoReplyService.Business.ExchangeAutoReply.AutoReplyToSender(ExchangeService service, 

    String mailboxEmailId))

    Awaiting for the reply.

    Thanks in advance :)

    Regards
    Jagdish Kotian

    Jagdish

    Thursday, December 5, 2013 6:44 AM
  • That error indicate the Item with that Id doesn't exist (or you don't have permissions to it are the Items IRM protected or marked as Private). 

    If you saying it works sometimes and fails others how do you know that another client (Outlook,OWA,ActiveSync,Blackberry etc) isn't moving or deleting the Items in the Mailbox between the FindItem and Bind your having a problem with (eg Exchange doesn't lock the records you need to validate the error if its telling you the Item isn't there you need to see if it is). As I mentioned you should try to debug and capture the ItemId's your having a problem with. If your using FindItems to get the Messages you can get a lot more details about the messages that are causing the problem. You can also use something like ExMon to view what other clients are accessing a Mailbox and what they are doing http://www.microsoft.com/en-au/download/details.aspx?id=11461 .

    Cheers
    Glen

    Friday, December 6, 2013 12:18 AM
  • Hi Glen,

    Thanks for the reply.

    I got one solution.

    I increased the time interval of Windows Service (WS) from 5 second to 2 minutes.

    In this case windows service executes every 2 minutes instead of 5 seconds. 

    Due to multiple loop of difference instance  with in 5 seconds.  First loops moves the mail to inbox other loop tries to move which is already moved this is the cause of error for "Binding" as well for "Moving".

    This is not a full proof solution because if in Inbox there is lots of mail which takes to execute more then 2 minutes for first loop of WS - after 2 minutes second loop of WS will executes - in this case error occurs again. - any solution for this let me know.


    Regards,

    Jagdish Kotian


    Jagdish

    Friday, December 6, 2013 11:10 AM
  • Hello Jagdish,

    have you considered making your application/service self-aware?
    So that the second iteration will wait until the first is done, no matter how long that takes ...

    Otherwise you'll loose performance during lower load times, because it'll only run only every X minutes, even if it's finished after 20 seconds. So this way you could make it more or less a continuously running service (which in turn will minimize item buildup in the inbox).

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Friday, December 6, 2013 11:41 AM
  • Hi Fred,

    Next am making service self-aware which is not done.

    It is new for me just Started...

    Thanks

    Jagdish Kotian


    Jagdish

    Friday, December 6, 2013 12:18 PM
  • Hi Fred,

    Give me some URL  about  how to make application/service self-aware.

    Thanks & Regards,

    Jagdish


    Jagdish

    Monday, December 9, 2013 11:59 AM
  • I got the Answer 

    Threading with Mutex (Mutual exclusion):

    When two or more threads need to access a shared resource at the same time, the system needs a synchronization mechanism to ensure that only one thread at a time uses the resource. Mutex is a synchronization primitive that grants exclusive access to the shared resource to only one thread. If a thread acquires a mutex, the second thread that wants to acquire that mutex is suspended until the first thread releases the mutex.

    Steps:

    • Instantiating a new Mutex object that's accessible from each thread.
    • Wrapping whatever code you want to be executed in the critical section with that object's WaitOne() and ReleaseMutex() methods in each thread

    Implementation:

    • Add class SingleGlobalInstance to your project

    1. class SingleGlobalInstance : IDisposable
    2. {
    3.     public bool hasHandle = false;
    4.     Mutex mutex;
    5.     private void InitMutex()
    6.     {
    7.         string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
    8.         string mutexId = string.Format("Global\\{{{0}}}", appGuid);
    9.         mutex = new Mutex(false, mutexId);
    10.         var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
    11.         var securitySettings = new MutexSecurity();
    12.         securitySettings.AddAccessRule(allowEveryoneRule);
    13.         mutex.SetAccessControl(securitySettings);
    14.     }
    15.     public SingleGlobalInstance(int TimeOut)
    16.     {
    17.         InitMutex();
    18.         try
    19.         {
    20.             if(TimeOut <= 0)
    21.                 hasHandle = mutex.WaitOne(Timeout.Infinite, false);
    22.             else
    23.                 hasHandle = mutex.WaitOne(TimeOut, false);
    24.             if (hasHandle == false)
    25.                 throw new TimeoutException("Timeout waiting for exclusive access on SingleInstance");
    26.         }
    27.         catch (AbandonedMutexException)
    28.         {
    29.             hasHandle = true;
    30.         }
    31.     }
    32.     public void Dispose()
    33.     {
    34.         if (mutex != null)
    35.         {
    36.             if (hasHandle)
    37.                 mutex.ReleaseMutex();
    38.             mutex.Dispose();
    39.         }
    40.     }
    41. }
      • Add following condition to check whether thread is already running

    using (new SingleGlobalInstance(1000))

    {

       //code which should be executed in single thread

     }

    Regards,

    Jagdish Kotian


    Jagdish

    • Marked as answer by Jagdish Kotian Tuesday, December 24, 2013 8:39 AM
    Tuesday, December 24, 2013 8:39 AM