I am currently working on a SharePoint online project. I am facing a strange issue. My code generates 6 documents in 6 different document libraries along with other metadata. When I save data to a List, the event receiver fires and creates all the 6 documents. But sometimes it stops creating the 6 documents and left with 1 or 2 documents. Sometimes documents has been created but without any metadata. The same code is working fine in my on-premises environment, but it sometimes breaks in the Office 365 environment. I also created a log list to track the issue as we cannot debug in Office 365. In the log list I found a error message saying "Thread was being aborted." Below is my code. please help it is happening only in Office 365 environment.
using Microsoft.SharePoint; /// <summary> /// List Item Events /// </summary> public class ExcelGenReceiver : SPItemEventReceiver { /// <summary> /// The template URL /// </summary> private const string TemplateUrl = "/Quotation Analysis Electrical/Forms/Quotation Analysis Sheet ELEC_Blank.xlsm"; /// <summary> /// The template url1 /// </summary> private const string TemplateUrl1 = "/Quotation Analysis Mechanical/Forms/Quotation Analysis Sheet MECH_Blank.xlsm"; /// <summary> /// The template url2 /// </summary> private const string TemplateUrl2 = "/TenderSummaryLib/Forms/TenderSummaryBlankMaster1.xlsm"; /// <summary> /// The RFI template URL /// </summary> private const string RfiTemplateUrl = "/EstimatingRFI/Forms/RFI Schedule MASTER.docx"; /// <summary> /// The drawing template URL /// </summary> private const string DrawingTemplateUrl = "/Tender and Drawing Schedule/Forms/Tender Document Drawing Schedule.docx"; /// <summary> /// The tender return template URL /// </summary> private const string TenderReturnTemplateUrl = "/Est_Tender_Pricing_Document/Forms/Tender Pricing Document blank.xlsm"; /// <summary> /// The project number /// </summary> private string projectNumber = string.Empty; /// <summary> /// The project name /// </summary> private string projectName = string.Empty; /// <summary> /// The no bid /// </summary> private string noBid; /// <summary> /// The team /// </summary> private string team; /// <summary> /// The description /// </summary> private string description; /// <summary> /// The status /// </summary> private string status; /// <summary> /// The electrical /// </summary> private SPUser electrical; /// <summary> /// The mechanical /// </summary> private SPUser mechanical; /// <summary> /// The document date /// </summary> private DateTime? docDate; /// <summary> /// The tender received /// </summary> private DateTime? tenderReceived; /// <summary> /// The tender return /// </summary> private DateTime? tenderReturn; /// <summary> /// The pre construction program start date /// </summary> private DateTime? preConstructionProgramStart; /// <summary> /// The pre construction program end date /// </summary> private DateTime? preConstructionProgramEnd; /// <summary> /// The sector /// </summary> private string sector; /// <summary> /// The design build /// </summary> private string designBuild; /// <summary> /// The build type /// </summary> private string buildType; /// <summary> /// The service program start date /// </summary> private DateTime? serviceProgramStart; /// <summary> /// The service program completion date /// </summary> private DateTime? serviceProgramCompletion; /// <summary> /// The client1 /// </summary> private string client1; /// <summary> /// The client2 /// </summary> private string client2; /// <summary> /// The client3 /// </summary> private string client3; /// <summary> /// The client4 /// </summary> private string client4; /// <summary> /// The consultant /// </summary> private string consultant; /// <summary> /// An item is being added. /// </summary> /// <param name="properties">The Item Event properties</param> public override void ItemAdded(SPItemEventProperties properties) { //this.EventFiringEnabled = false; var web = properties.Web; var listItem = properties.ListItem; try { LogIssue(web, null, "Item Added", "List Item Id {0}", listItem.ID); if (!this.AttemptCopyProcess(listItem)) { LogIssue(web, null, "List Id : " + listItem.ID, "AttemptCopyProcess failed."); } } catch (Exception ex) { LogIssue(web, ex, "List Id : " + listItem.ID, "AttemptCopyProcess failed."); } finally { //this.EventFiringEnabled = true; LogIssue(web, null, "List Id : " + listItem.ID, "Event Receiver completed sucessfully."); } } /// <summary> /// Logs any issues found /// </summary> /// <param name="webContext">The web context.</param> /// <param name="exception">The exception, if null not exception details are written</param> /// <param name="contextId">The context identifier, a unique identifier that allows us to know where the call originated, i.e. a List and ListItem Id, or a Page Url</param> /// <param name="comment">The comment.</param> /// <param name="args">The arguments.</param> private static void LogIssue(SPWeb webContext, Exception exception, string contextId, string comment, params object[] args) { //// if (webContext.AllProperties.ContainsKey("EnableLogging")) //// { var list = webContext.Lists.TryGetList("ErrorIssues"); if (list != null) { var item = list.AddItem(); item["Title"] = contextId; if (exception != null) { item["Message"] = exception.Message; item["InnerException"] = exception.InnerException ?? (object)string.Empty; item["StackTrace"] = exception.StackTrace; } if (!string.IsNullOrEmpty(comment)) { item["Comment"] = string.Format(comment, args); } item.Update(); } //// } } /// <summary> /// Assigns the field. /// </summary> /// <param name="listItem">The list item.</param> /// <param name="fieldName">Name of the field.</param> /// <param name="contextId">The context identifier.</param> /// <returns>The fields string value if present, otherwise string.empty.</returns> private static string AssignField(SPListItem listItem, string fieldName, string contextId) { var fieldValue = string.Empty; if (listItem.Fields.ContainsField(fieldName) && listItem[fieldName] != null) { fieldValue = listItem[fieldName].ToString(); } else { LogIssue(listItem.Web, null, contextId, string.Format("Field not available : {0}", fieldName)); } return fieldValue; } /// <summary> /// Assigns the field as a DateTime /// </summary> /// <param name="listItem">The list item.</param> /// <param name="fieldName">Name of the field.</param> /// <param name="contextId">The context identifier.</param> /// <returns>Returns the date if found, otherwise returns DateTime.MinValue</returns> private static DateTime? AssignDateField(SPListItem listItem, string fieldName, string contextId) { DateTime? fieldValue = null; if (listItem.Fields.ContainsField(fieldName) && listItem[fieldName] != null) { fieldValue = Convert.ToDateTime(listItem[fieldName].ToString()); } else { LogIssue(listItem.Web, null, contextId, string.Format("Field not available : {0}", fieldName)); } return fieldValue; } /// <summary> /// Creates the folder. /// </summary> /// <param name="listdoc">The list.</param> /// <param name="folderName">Name of the folder.</param> private static void CreateFolder(SPList listdoc, string folderName) { LogIssue(listdoc.ParentWeb, null, "List Id : " + listdoc.ID, "Creating folder {0} in {1}", folderName, listdoc.RootFolder.ServerRelativeUrl); // Updated by Indusnet SPListItem folder1 = listdoc.Items.Add(listdoc.RootFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder); folder1["Name"] = folderName; folder1.Update(); listdoc.Update(); // End Updated } /// <summary> /// Assigns the user field. /// </summary> /// <param name="listItem">The list item.</param> /// <param name="fieldName">Name of the field.</param> /// <param name="contextId">The context identifier.</param> /// <returns>Returns the user if found, otherwise null.</returns> private static SPUser AssignUserField(SPListItem listItem, string fieldName, string contextId) { SPUser user = null; if (listItem.Fields.ContainsField(fieldName) && listItem[fieldName] != null) { var userField = (SPFieldUser)listItem.Fields.GetField(fieldName); var fieldValue = (SPFieldUserValue)userField.GetFieldValue(listItem["electrical_proj_manager"].ToString()); user = fieldValue.User; } else { LogIssue(listItem.Web, null, contextId, string.Format("Field not available : {0}", fieldName)); } return user; } /// <summary> /// Attempts the copy process. /// </summary> /// <param name="listItem">The list item.</param> /// <returns>True if it successfully processed, false otherwise.</returns> private bool AttemptCopyProcess(SPListItem listItem) { if (listItem.ParentList.Title != "Enquiry_Template") { LogIssue(listItem.Web, null, "List Id : " + listItem.ID, "ListItem titles is not Enquiry_Template, aborting."); return false; } var finalNum = "15-" + new Random().Next(0, 9999).ToString("D4"); this.Initialize(listItem, finalNum); if (this.noBid != "Yes") { LogIssue(listItem.Web, null, "List Id : " + listItem.ID, "The noBid field does not equal Yes, aborting."); return false; } this.CopyFiles(listItem.Web, finalNum); this.CreateFolders(listItem.Web); return true; } /// <summary> /// Copies the files. /// </summary> /// <param name="web">The web.</param> /// <param name="finalNum">The final number.</param> private void CopyFiles(SPWeb web, string finalNum) { LogIssue(web, null, "Web Id : " + web.ID, "Setting the copying of files ..."); var mechanicalQuoteList = web.Lists["Quotation Analysis Mechanical"]; var electricalQuoteList = web.Lists["Quotation Analysis Electrical"]; var tenderSummarList = web.Lists["TenderSummaryLib"]; var estimatingList = web.Lists["EstimatingRFI"]; var tenderSheduleList = web.Lists["Tender and Drawing Schedule"]; var tenderPricingList = web.Lists["Est_Tender_Pricing_Document"]; var url1 = mechanicalQuoteList.RootFolder.ServerRelativeUrl; var url = electricalQuoteList.RootFolder.ServerRelativeUrl; var url2 = tenderSummarList.RootFolder.ServerRelativeUrl; var urlA = estimatingList.RootFolder.ServerRelativeUrl; var urlB = tenderSheduleList.RootFolder.ServerRelativeUrl; var urlC = tenderPricingList.RootFolder.ServerRelativeUrl; var foldername1 = string.Empty; var foldername = string.Empty; var foldername2 = string.Empty; var foldernameA = string.Empty; var foldernameB = string.Empty; var foldernameC = string.Empty; var folder1 = web.Folders[url1 + "/" + foldername1]; var folder = web.Folders[url + "/" + foldername]; var folder2 = web.Folders[url2 + "/" + foldername2]; var folderA = web.Folders[urlA + "/" + foldernameA]; var folderB = web.Folders[urlB + "/" + foldernameB]; var folderC = web.Folders[urlC + "/" + foldernameC]; if (!folder1.Exists && !folder.Exists && !folder2.Exists && !folderA.Exists && !folderB.Exists && !folderC.Exists) { var folders1 = web.GetFolder(url1).SubFolders; var folders = web.GetFolder(url).SubFolders; var folders2 = web.GetFolder(url2).SubFolders; var foldersA = web.GetFolder(urlA).SubFolders; var foldersB = web.GetFolder(urlB).SubFolders; var foldersC = web.GetFolder(urlC).SubFolders; folders1.Add(foldername1); folders.Add(foldername); folders2.Add(foldername2); foldersA.Add(foldernameA); foldersB.Add(foldernameB); foldersC.Add(foldernameC); } var file1 = web.GetFile(web.Site.Url + TemplateUrl1); var file = web.GetFile(web.Site.Url + TemplateUrl); var file2 = web.GetFile(web.Site.Url + TemplateUrl2); var fileA = web.GetFile(web.Site.Url + RfiTemplateUrl); var fileB = web.GetFile(web.Site.Url + DrawingTemplateUrl); var fileC = web.GetFile(web.Site.Url + TenderReturnTemplateUrl); if (file1 != null && file != null && file2 != null && fileA != null && fileB != null && fileC != null) { var fileName = string.Format("{0}/{1}{2}", folder1.ServerRelativeUrl, this.projectName, ".xlsm"); LogIssue(web, null, "Web Id : " + web.ID, "Copying file 1 {0} to {1}...", file1.Name, fileName); var byteArray1 = file1.OpenBinary(); var uploadedFile1 = folder1.Files.Add(fileName, byteArray1, true); LogIssue(web, null, "Web Id : " + web.ID, "File 1 Uploaded with new ID of {0}", uploadedFile1.Item.ID); this.EventFiringEnabled = false; var listitem1 = uploadedFile1.Item; listitem1["Name"] = this.projectName; listitem1["EnquiryNo"] = finalNum; listitem1["Project_Name"] = this.projectName; listitem1["Tender_Received"] = this.tenderReceived; listitem1["Tender_Return"] = this.tenderReturn; listitem1["Quotation_Analysis_Mech_Url"] = "https://groupportal.sharepoint.com/sites/EnginSouth/Quotation%20Analysis%20Mechanical/Forms/DispForm.aspx?ID=" + listitem1.ID; listitem1.SystemUpdate(false); this.EventFiringEnabled = true; LogIssue(web, null, "Web Id : " + web.ID, "Copied file 1."); fileName = string.Format("{0}/{1}{2}", folder.ServerRelativeUrl, this.projectName, ".xlsm"); LogIssue(web, null, "Web Id : " + web.ID, "Copying file 2 {0} to {1}...", file.Name, fileName); var byteArray = file.OpenBinary(); var uploadedFile = folder.Files.Add(fileName, byteArray, true); LogIssue(web, null, "Web Id : " + web.ID, "File 2 Uploaded with new ID of {0}", uploadedFile.Item.ID); this.EventFiringEnabled = false; var listitem = uploadedFile.Item; listitem["Name"] = this.projectName; listitem["EnquiryNo"] = finalNum; listitem["Project_Name"] = this.projectName; listitem["Tender_Received"] = this.tenderReceived; listitem["Tender_Return"] = this.tenderReturn; listitem["Quotation_Analysis_Elec_Url"] = "https://groupportal.sharepoint.com/sites/EnginSouth/Quotation%20Analysis%20Electrical/Forms/DispForm.aspx?ID=" + listitem.ID; listitem.SystemUpdate(false); this.EventFiringEnabled = true; LogIssue(web, null, "Web Id : " + web.ID, "Copied file 2."); fileName = string.Format("{0}/{1}{2}", folderA.ServerRelativeUrl, this.projectName, ".docx"); LogIssue(web, null, "Web Id : " + web.ID, "Copying file 3 {0} to {1}...", fileA.Name, fileName); var byteArrayA = fileA.OpenBinary(); var uploadedFileA = folderA.Files.Add(fileName, byteArrayA, true); LogIssue(web, null, "Web Id : " + web.ID, "File 3 Uploaded with new ID of {0}", uploadedFileA.Item.ID); this.EventFiringEnabled = false; var listitemA = uploadedFileA.Item; listitemA["Name"] = this.projectName; listitemA["EnquiryNo"] = finalNum; listitemA["Project_Name"] = this.projectName; listitemA["Date"] = this.docDate; listitemA["Description"] = this.description; listitemA["ProjectNo"] = this.projectNumber; listitemA["RFIUrl"] = "https://groupportal.sharepoint.com/sites/EnginSouth/EstimatingRFI/Forms/DispForm.aspx?ID=" + listitemA.ID; listitemA.SystemUpdate(false); this.EventFiringEnabled = true; LogIssue(web, null, "Web Id : " + web.ID, "Copied file 3."); fileName = string.Format("{0}/{1}{2}", folderB.ServerRelativeUrl, this.projectName, ".docx"); LogIssue(web, null, "Web Id : " + web.ID, "Copying file 4 {0} to {1}...", fileB.Name, fileName); var byteArrayB = fileB.OpenBinary(); var uploadedFileB = folderB.Files.Add(fileName, byteArrayB, true); LogIssue(web, null, "Web Id : " + web.ID, "File 4 Uploaded with new ID of {0}", uploadedFileB.Item.ID); this.EventFiringEnabled = false; var listitemB = uploadedFileB.Item; listitemB["Name"] = this.projectName; listitemB["EnquiryNo"] = finalNum; listitemB["Project_Name"] = this.projectName; listitemB["Date"] = this.docDate; listitemB["Description"] = this.description; listitemB["ProjectNo"] = this.projectNumber; listitemB["DrawingURL"] = "https://groupportal.sharepoint.com/sites/EnginSouth/Tender%20and%20Drawing%20Schedule/Forms/DispForm.aspx?ID=" + listitemB.ID; listitemB.SystemUpdate(false); this.EventFiringEnabled = true; LogIssue(web, null, "Web Id : " + web.ID, "Copied file 4."); fileName = string.Format("{0}/{1}{2}", folderC.ServerRelativeUrl, this.projectName, ".xlsm"); LogIssue(web, null, "Web Id : " + web.ID, "Copying file 5 {0} to {1}...", fileC.Name, fileName); var byteArrayC = fileC.OpenBinary(); var uploadedFileC = folderC.Files.Add(fileName, byteArrayC, true); LogIssue(web, null, "Web Id : " + web.ID, "File 5 Uploaded with new ID of {0}", uploadedFileC.Item.ID); this.EventFiringEnabled = false; var listitemC = uploadedFileC.Item; listitemC["Name"] = this.projectName; listitemC["EnquiryNo"] = finalNum; listitemC["Project_Name"] = this.projectName; listitemC["Date"] = this.docDate; listitemC["Description"] = this.description; listitemC["ProjectNo"] = this.projectNumber; listitemC["PricingURL"] = "https://groupportal.sharepoint.com/sites/EnginSouth/Est_Tender_Pricing_Document/Forms/DispForm.aspx?ID=" + listitemC.ID; listitemC.SystemUpdate(false); this.EventFiringEnabled = true; LogIssue(web, null, "Web Id : " + web.ID, "Copied file 5."); fileName = string.Format("{0}/{1}{2}", folder2.ServerRelativeUrl, this.projectName, ".xlsm"); LogIssue(web, null, "Web Id : " + web.ID, "Copying file 5 {0} to {1}...", file2.Name, fileName); var byteArray2 = file2.OpenBinary(); var uploadedFile2 = folder2.Files.Add(fileName, byteArray2, true); LogIssue(web, null, "Web Id : " + web.ID, "File 6 Uploaded with new ID of {0}", uploadedFile2.Item.ID); this.EventFiringEnabled = false; var listitem2 = uploadedFile2.Item; listitem2["Name"] = this.projectName; listitem2["EnquiryNo"] = finalNum; listitem2["Project_Name"] = this.projectName; listitem2["Date"] = this.docDate; listitem2["Team"] = this.team; listitem2["Estimator_Electrical"] = this.electrical; listitem2["Estimator_Mechanical"] = this.mechanical; listitem2["Status"] = this.status; listitem2["Tender_Received"] = this.tenderReceived; listitem2["Tender_Return"] = this.tenderReturn; listitem2["Sector"] = this.sector; listitem2["Design_Build"] = this.designBuild; listitem2["Build_Type"] = this.buildType; listitem2["Service_Prog_Start"] = this.serviceProgramStart; listitem2["Service_Prog_Completion"] = this.serviceProgramCompletion; listitem2["Client_1"] = this.client1; listitem2["Client_2"] = this.client2; listitem2["Client_3"] = this.client3; listitem2["Client_4"] = this.client4; listitem2["Consultant"] = this.consultant; listitem2["Pre-construction_Prog_Start"] = this.preConstructionProgramStart; listitem2["Pre-construction_Prog_End"] = this.preConstructionProgramEnd; listitem2["Tender_Summary_Url"] = "https://groupportal.sharepoint.com/sites/EnginSouth/TenderSummaryLib/Forms/DispForm.aspx?ID=" + listitem2.ID; listitem2.SystemUpdate(false); this.EventFiringEnabled = true; LogIssue(web, null, "Web Id : " + web.ID, "Copied file 6."); } } /// <summary> /// Creates the folders. /// </summary> /// <param name="web">The web.</param> private void CreateFolders(SPWeb web) { var projectListId = web.Lists.Add(this.projectName.Replace(' ', '_'), string.Empty, SPListTemplateType.DocumentLibrary); var projectList = web.Lists[projectListId]; projectList.OnQuickLaunch = true; // The document library will appear in Quick Launch bar. CreateFolder(projectList, "1.Tender Documents"); CreateFolder(projectList, "2. Electrical"); CreateFolder(projectList, "3. Mechanical"); CreateFolder(projectList, "4. Correspondance"); CreateFolder(projectList, "5. Settlement Meeting Docs"); CreateFolder(projectList, "6. Tender Return Docs"); CreateFolder(projectList, "7. Tender Handover"); projectList.Update(); } /// <summary> /// Initializes the specified list item. /// </summary> /// <param name="listItem">The list item.</param> /// <param name="finalNum">The final number.</param> private void Initialize(SPListItem listItem, string finalNum) { var contextId = string.Format("List:{0}, Id:{1}", listItem.ParentList.Title, listItem.ID); this.noBid = AssignField(listItem, "Bid", contextId); this.projectName = AssignField(listItem, "Project_Name", contextId); var teamlookup = AssignField(listItem, "Team", contextId); var lookupParts = teamlookup.Split(new[] { ";#" }, StringSplitOptions.None); this.team = lookupParts[1]; this.description = AssignField(listItem, "Description", contextId); this.status = AssignField(listItem, "enquiry_status", contextId); this.electrical = AssignUserField(listItem, "electrical_proj_manager", contextId); this.mechanical = AssignUserField(listItem, "mechanical_proj_manager", contextId); this.docDate = AssignDateField(listItem, "Date", contextId); this.tenderReceived = AssignDateField(listItem, "Tender_Received", contextId); this.tenderReturn = AssignDateField(listItem, "Tender_Return", contextId); this.preConstructionProgramStart = AssignDateField(listItem, "Pre-construction_Prog_Start", contextId); this.preConstructionProgramEnd = AssignDateField(listItem, "Pre-construction_Prog_End", contextId); this.sector = AssignField(listItem, "Sector", contextId); this.designBuild = AssignField(listItem, "Design_Build", contextId); this.buildType = AssignField(listItem, "Build_Type", contextId); this.serviceProgramStart = AssignDateField(listItem, "Service_Prog_Start", contextId); this.serviceProgramCompletion = AssignDateField(listItem, "Service_Prog_Completion", contextId); this.client1 = AssignField(listItem, "Client_1", contextId); this.client2 = AssignField(listItem, "Client_2", contextId); this.client3 = AssignField(listItem, "Client_3", contextId); this.client4 = AssignField(listItem, "Client_4", contextId); this.consultant = AssignField(listItem, "Consultant", contextId); if (this.status == "Won") { this.projectNumber = string.Format("15-{0}-{1}", this.team, new Random().Next(0, 9999).ToString("D4")); } if (this.status == "Active" || this.status == "Closed") { this.projectNumber = "No Project No"; } listItem["ProjectNo"] = this.projectNumber; listItem["EnquiryNo"] = finalNum; listItem.Web.AllowUnsafeUpdates = true; listItem.SystemUpdate(false); } }