none
Update email category - EXCEPTION MESSAGE: Access is denied. Check credentials and try again. RRS feed

  • Question

  • Hi,

    I have to create small application to import emails from Sent Items to database and set my category for email.

    I receive exception message "Access is denied. Check credentials and try again." when I update email categories.

    I test my application on Office365.
    I have no multithreading.
    My code works until I don't send any email.
    I prepare small sample:

    internal static class Program
        {
            private static CategoryColor _categoryColor;
            public static string CategoryName { get; set; }

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [MTAThread]
            private static void Main()
            {
                CategoryName = "CL - Test 1";
                _categoryColor = CategoryColor.Green;

                FillCategory();

                SynchronizeChangesPeriodically();

                Console.ReadLine();
            }

            private static void SynchronizeChangesPeriodically()
            {
                ExchangeService exchangeService = CommonUtils.GetExchangeService();
                string syncState = null;

                while (true)
                {
                    DateTime beginSyncTime = DateTime.Now;

                    try
                    {
                        bool moreChangesAvailable;
                        do
                        {
                            // Get all changes since the last call. The synchronization cookie is stored in the _SynchronizationState field.
                            // Only the the ids are requested. Additional properties should be fetched via GetItem calls.
                            ChangeCollection<ItemChange> changes =
                                exchangeService.SyncFolderItems(new FolderId(WellKnownFolderName.SentItems),
                                    PropertySet.IdOnly, null, 512, SyncFolderItemsScope.NormalItems, syncState);

                            StartImport(exchangeService, changes);

                            syncState = changes.SyncState;

                            // If more changes are available, issue additional SyncFolderItems requests.
                            moreChangesAvailable = changes.MoreChangesAvailable;
                        } while (moreChangesAvailable);
                    }
                    catch (Exception ex)
                    {
                        throw;
                    }

                    TimeSpan syncDuration = DateTime.Now - beginSyncTime;
                    int sleep = 15 - syncDuration.Seconds;
                    if (sleep > 0)
                    {
                        Thread.Sleep(TimeSpan.FromSeconds(sleep));
                    }
                }
            }

            private static void StartImport(ExchangeService exchangeService, ChangeCollection<ItemChange> changes)
            {
                List<ItemChange> newItems = changes.Where(c => c.ChangeType == ChangeType.Create).ToList();
                List<ItemId> list = newItems.Select(i => i.ItemId).ToList();

                if (list.Count != 0)
                {
                    PropertySet propertySet = new PropertySet(BasePropertySet.FirstClassProperties)
                    {
                        RequestedBodyType = BodyType.HTML
                    };

                    ServiceResponseCollection<GetItemResponse> items = exchangeService.BindToItems(list, propertySet);

                    List<Item> res = items.Select(i => i.Item).ToList();
                    if (res.Count != 0)
                    {
                        foreach (EmailMessage msg in res)
                        {
                            Import(msg);
                        }
                    }
                }
            }

            private static void Import(EmailMessage msg)
            {
                StringBuilder logMessage = null;
                try
                {
                    logMessage = new StringBuilder();
                    logMessage.Append("TreadID: ")
                        .Append(Thread.CurrentThread.ManagedThreadId)
                        .AppendLine()
                        .Append("E-mail subject: ").Append(msg.Subject).AppendLine()
                        .Append("Inet ID Imported: ").Append(msg.InternetMessageId).AppendLine()
                        .Append("DateTimeCreated: ").Append(msg.DateTimeCreated).AppendLine()
                        .Append("DateTimeReceived: ").Append(msg.DateTimeReceived).AppendLine()
                        .Append("# of Contacts Imported: ")
                        .AppendLine();


                    Thread.Sleep(100);

                    string newCategory = CategoryName;

                    try
                    {
                        if (!msg.Categories.Contains(newCategory))
                        {
                            msg.Categories.Add(newCategory);
                            msg.Update(ConflictResolutionMode.AutoResolve);
                        }
                    }
                    catch (Exception e)
                    {
                        throw;
                        Thread.Sleep(500);
                        try
                        {
                            ExchangeService service = CommonUtils.GetExchangeService();
                            EmailMessage emailMessage = EmailMessage.Bind(service, msg.Id);

                            if (!emailMessage.Categories.Contains(newCategory))
                                // strange... - sometimes msg.Categories already contains newCategory...
                            {
                                emailMessage.Categories.Add(newCategory);
                                emailMessage.Update(ConflictResolutionMode.AutoResolve);
                            }
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                }
                catch (Exception e)
                {
                    throw;
                }
                finally
                {
                    if (logMessage != null)
                    {
                        Console.WriteLine(logMessage.ToString());
                    }
                }
            }

            public static void FillCategory()
            {
                try
                {
                    ExchangeService exchangeService = CommonUtils.GetExchangeService();

                    MasterCategoryList list = MasterCategoryList.Bind(exchangeService);
                    Category category = list.Categories.FirstOrDefault(c => c.Name == CategoryName);

                    if (category == null)
                    {
                        list.Categories.Add(new Category(CategoryName, _categoryColor, CategoryKeyboardShortcut.CtrlF3));
                        list.Update();
                    }
                }
                catch (Exception e)
                {
                    throw;
                }
            }
        }

    It very offen cores in row:
    emailMessage.Update(ConflictResolutionMode.AutoResolve);

    I catch it and try to update category again. Sometimes it works. Sometimes it doesn't work.

    Scenario isn't stable and reproduce during sending a lot of emails.

    Why does this issue happen? How can I fix it?

    I will be grateful for any your ideas and advice.

    Thanks.

    Friday, February 21, 2014 2:01 PM

All replies

  • Hi,

    You can download my sample
    https://drive.google.com/file/d/0B_SiEmYUsO-QS242X3g4QktUN1U/edit?usp=sharing

    This solution contains 2 project.

    First project sends emails by exchange second project impotrs them.
    You have to change EMAIL and PASS in class CommonUtils.
    And you should run this project together to show this issue.

    Thanks.

    Ideas ?

    Friday, February 21, 2014 2:13 PM
  • Hi,

    maybe is it because of EWS throttling policies in Office 365 ?

    Do you known how many emails you can send/update before it starts throwing exceptions ? And how long does it take to reach this threshold ?

    Regards,


    Désiré GOVIN Refresh IT Solutions

    Friday, February 21, 2014 2:37 PM
  • Maybe something to do with the ExchangeCookie, I'd suggest you add the affinity header to make sure your request aren't hitting issue with the load balancer eg

            public static ExchangeService GetExchangeService()
            {
                ExchangeService exchangeService = new ExchangeService()
                {
                    Url = new Uri(URI),
                    Credentials = new WebCredentials(EMAIL, PASS)
                    
                };
                exchangeService.HttpHeaders.Add("X-AnchorMailbox", EMAIL);            
                return exchangeService;
            }

    There also is a Recipient Rate limit you might be hitting http://technet.microsoft.com/en-us/library/exchange-online-limits.aspx

    Cheers
    Glen

    Monday, February 24, 2014 4:09 AM
  • It has sense...
    I try to change my code.

    Thanks.
    Tuesday, February 25, 2014 2:02 PM
  • Thank you :)
    Tuesday, February 25, 2014 2:03 PM