private void TransferData(EntityCollection ec, IOrganizationService service) { // References to websites var webSitesRefId = ec.Entities.SelectMany(e => e.Attributes) .Where(a => a.Value is EntityReference reference && reference.LogicalName == "adx_website") .Select(a => ((EntityReference)a.Value).Id) .Distinct() .ToList(); // Websites included in records to process var webSitesIds = ec.Entities.Where(e => e.LogicalName == "adx_website") .Select(e => e.Id) .ToList(); // If some references are not found in websites included in records // to process, ask the user to map to the appropriate website if (!webSitesRefId.All(id => webSitesIds.Contains(id))) { try { var targetWebSites = service.RetrieveMultiple(new QueryExpression("adx_website") { ColumnSet = new ColumnSet("adx_name") }).Entities; if (!webSitesRefId.All(id => targetWebSites.Select(w => w.Id).Contains(id))) { var wsmDialog = new WebSiteMapper(ec, targetWebSites.Select(t => new Website(t)).ToList()); if (wsmDialog.ShowDialog() == DialogResult.Cancel) { return; } } } catch (FaultException <OrganizationServiceFault> error) { if (error.Detail.ErrorCode == -2147217150) { MessageBox.Show(this, @"The target environment does not seem to have Portals solutions installed!", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show(this, $@"An unknown error occured when searching for websites: {error.Detail.Message}", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } pnlImport.SendToBack(); tsMain.Enabled = true; return; } } var pluginCheck = ec.Entities.Any(e => e.LogicalName == "adx_webpage"); var javascriptCheck = ec.Entities.Any(e => e.LogicalName == "annotation" && (e.GetAttributeValue <string>("filename")?.ToLower().EndsWith(".js") ?? false)) && nManager.HasJsRestriction; var webFileCleaning = ec.Entities.Any(e => e.LogicalName == "annotation" && e.GetAttributeValue <EntityReference>("objectid")?.LogicalName == "adx_webfile"); if (pluginCheck || javascriptCheck) { var dialog = new PreImportWarningDialog(pluginCheck, javascriptCheck, webFileCleaning); var result = dialog.ShowDialog(this); if (result == DialogResult.Cancel) { return; } iSettings.DeactivateWebPagePlugins = true; iSettings.RemoveJavaScriptFileRestriction = true; iSettings.CleanWebFiles = dialog.CleanWebFiles; } var lm = new LogManager(GetType()); if (File.Exists(lm.FilePath)) { if (MessageBox.Show(this, @"A log file already exists. Would you like to create a new log file?", @"Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { File.Copy(lm.FilePath, $"{lm.FilePath.Substring(0, lm.FilePath.Length - 4)}-{DateTime.Now:yyyyMMdd_HHmmss}.txt", true); File.Delete(lm.FilePath); } } btnCancel.Visible = true; btnImport.Enabled = false; pnlImportMain.Visible = true; pbImport.IsOnError = false; lvProgress.Items.Clear(); var worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; worker.DoWork += (s, evt) => { importWorker = (BackgroundWorker)s; if (emds.Count == 0) { AddTile("Retrieve metadata", "We need entities metadata to process your records"); emds = MetadataManager.GetEntitiesList(service); CompleteTile(); } if (iSettings.DeactivateWebPagePlugins) { AddTile("Disable plugins", "We need to disable web page plugins to ensure we don't create duplicates"); logger.LogInfo("Deactivating Webpage plugins steps"); pManager = new PluginManager(service); pManager.DeactivateWebpagePlugins(); CompleteTile(); logger.LogInfo("Webpage plugins steps deactivated"); } if (iSettings.RemoveJavaScriptFileRestriction && nManager.HasJsRestriction) { AddTile("Remove file restriction", "We need to authorize JavaScript file type to create Web file correctly"); logger.LogInfo("Removing JavaScript file restriction"); nManager.RemoveRestriction(); // Wait 2 seconds to be sure the settings is updated Thread.Sleep(2000); CompleteTile(); logger.LogInfo("JavaScript file restriction removed"); } AddTile("Process records", "Records are processed in three phases : one phase without lookup being populated. A second phase with lookup being populated. This ensure all relationships between records can be created on the second phase. And a third phase to deactivate records that need it."); var rm = new RecordManager(service); evt.Cancel = rm.ProcessRecords((EntityCollection)evt.Argument, emds, ConnectionDetail.OrganizationMajorVersion, importWorker, iSettings); if (evt.Cancel) { CancelTile(); } else { CompleteTile(); } if (iSettings.DeactivateWebPagePlugins) { AddTile("Enable plugins", "We are enabling web page plugins so that your portal work smoothly"); logger.LogInfo("Reactivating Webpage plugins steps"); pManager.ActivateWebpagePlugins(); logger.LogInfo("Webpage plugins steps activated"); CompleteTile(); } if (iSettings.RemoveJavaScriptFileRestriction && nManager.HasJsRestriction) { AddTile("Add file restriction", "We are adding back restriction for JavaScript files."); logger.LogInfo("Adding back JavaScript file restriction"); importWorker.ReportProgress(0, "Adding back JavaScript file restriction..."); nManager.AddRestriction(); logger.LogInfo("JavaScript file restriction added back"); CompleteTile(); } }; worker.RunWorkerCompleted += (s, evt) => { llOpenLogFile.Visible = true; btnImportClose.Enabled = true; btnImport.Enabled = true; btnCancel.Visible = false; if (evt.Cancelled) { CancelTile(); lblProgress.Text = @"Import was canceled!"; return; } if (evt.Error != null) { CancelTile(); logger.LogError(evt.Error.ToString()); MessageBox.Show(this, $@"An error occured: {evt.Error.Message}", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(string.Empty)); lblProgress.Text = @"Records imported!"; if (pbImport.IsOnError) { MessageBox.Show(this, @"Import complete with errors Please review the logs", @"Information", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { MessageBox.Show(this, @"Import complete", @"Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } }; worker.ProgressChanged += (s, evt) => { if (evt.UserState is string) { lblProgress.Text = evt.UserState.ToString(); logger.LogInfo(evt.UserState.ToString()); SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(evt.UserState.ToString())); } else { if (evt.UserState is ImportProgress progress) { foreach (var ep in progress.Entities) { var item = lvProgress.Items.Cast <ListViewItem>().FirstOrDefault(i => i.Tag.ToString() == ep.LogicalName); if (item == null) { item = new ListViewItem($"{ep.Entity} ({ep.Count})") { Tag = ep.LogicalName }; item.SubItems.Add(ep.SuccessFirstPhase.ToString()); item.SubItems.Add(ep.ErrorFirstPhase.ToString()); item.SubItems.AddRange(new[] { "", "", "", "" }); if (ep.SuccessSecondPhase.HasValue || ep.ErrorSecondPhase.HasValue) { item.SubItems[3].Text = (ep.SuccessSecondPhase ?? 0).ToString(); item.SubItems[4].Text = (ep.ErrorSecondPhase ?? 0).ToString(); } if (ep.SuccessSetStatePhase.HasValue || ep.ErrorSetState.HasValue) { item.SubItems[5].Text = (ep.SuccessSetStatePhase ?? 0).ToString(); item.SubItems[6].Text = (ep.ErrorSetState ?? 0).ToString(); } lvProgress.Items.Add(item); } else { item.SubItems[1].Text = ep.SuccessFirstPhase.ToString(); item.SubItems[2].Text = ep.ErrorFirstPhase.ToString(); if (ep.SuccessSecondPhase.HasValue || ep.ErrorSecondPhase.HasValue) { item.SubItems[3].Text = (ep.SuccessSecondPhase ?? 0).ToString(); item.SubItems[4].Text = (ep.ErrorSecondPhase ?? 0).ToString(); } if (ep.SuccessSetStatePhase.HasValue || ep.ErrorSetState.HasValue) { item.SubItems[5].Text = (ep.SuccessSetStatePhase ?? 0).ToString(); item.SubItems[6].Text = (ep.ErrorSetState ?? 0).ToString(); } } item.ForeColor = ep.ErrorFirstPhase > 0 || ep.ErrorSecondPhase > 0 || ep.ErrorSetState > 0 ? Color.Red : Color.Green; if (ep.ErrorFirstPhase > 0 || ep.ErrorSecondPhase > 0 || ep.ErrorSetState > 0) { pbImport.IsOnError = true; } pbImport.Value = progress.Entities.Sum(ent => ent.Processed) * 100 / progress.Count; } } } }; worker.RunWorkerAsync(ec); }
private void Import() { if (txtImportFilePath.Text.Length == 0) { return; } if (!File.Exists(txtImportFilePath.Text)) { MessageBox.Show(this, $"The file {txtImportFilePath.Text} does not exist!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } btnCancel.Visible = true; lblProgress.Text = "Deserializing file..."; SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs("Deserializing file...")); EntityCollection ec; using (var reader = new StreamReader(txtImportFilePath.Text)) { var serializer = new DataContractSerializer(typeof(EntityCollection), new List <Type> { typeof(Entity) }); ec = (EntityCollection)serializer.ReadObject(reader.BaseStream); } // References to websites var webSitesRefId = ec.Entities.SelectMany(e => e.Attributes) .Where(a => a.Value is EntityReference reference && reference.LogicalName == "adx_website") .Select(a => ((EntityReference)a.Value).Id) .Distinct() .ToList(); // Websites included in records to process var webSitesIds = ec.Entities.Where(e => e.LogicalName == "adx_website") .Select(e => e.Id) .ToList(); // If some references are not found in websites included in records // to process, ask the user to map to the appropriate website if (!webSitesRefId.All(id => webSitesIds.Contains(id))) { var targetWebSites = Service.RetrieveMultiple(new QueryExpression("adx_website") { ColumnSet = new ColumnSet("adx_name") }).Entities; if (!webSitesRefId.All(id => targetWebSites.Select(w => w.Id).Contains(id))) { var wsmDialog = new WebSiteMapper(ec, targetWebSites.Select(t => new Website(t)).ToList()); if (wsmDialog.ShowDialog() == DialogResult.Cancel) { return; } } } if (ec.Entities.Any(e => e.LogicalName == "adx_webpage")) { var message = "You are trying to import web pages. It is recommended to deactivate plugins steps related to this entity to ensure successful import. Do you want to deactivate these plugins ? \n\nNote: The plugins will be reactivated at the end of the import process"; iSettings.DeactivateWebPagePlugins = MessageBox.Show(this, message, @"Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes; } if (ec.Entities.Any(e => e.LogicalName == "annotation" && (e.GetAttributeValue <string>("filename")?.ToLower().EndsWith(".js") ?? false)) && nManager.HasJsRestriction) { var message = "You are trying to import JavaScript note. It is recommended to remove JavaScript file type restriction to ensure successful import. Do you want to remove this restriction ? \n\nNote: The restriction will be added back at the end of the import process"; iSettings.RemoveJavaScriptFileRestriction = MessageBox.Show(this, message, @"Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes; } btnImport.Enabled = false; pnlImportMain.Visible = true; pbImport.IsOnError = false; lvProgress.Items.Clear(); var worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; worker.DoWork += (s, evt) => { importWorker = (BackgroundWorker)s; if (emds.Count == 0) { importWorker.ReportProgress(0, "Retrieving metadata..."); emds = MetadataManager.GetEntitiesList(Service); } if (iSettings.DeactivateWebPagePlugins) { importWorker.ReportProgress(0, "Deactivating Webpage plugins steps..."); logger.LogInfo("Deactivating Webpage plugins steps"); pManager = new PluginManager(Service); pManager.DeactivateWebpagePlugins(); logger.LogInfo("Webpage plugins steps deactivated"); } if (iSettings.RemoveJavaScriptFileRestriction && nManager.HasJsRestriction) { logger.LogInfo("Removing JavaScript file restriction"); importWorker.ReportProgress(0, "Removing JavaScript file restriction..."); nManager.RemoveRestriction(); // Wait 2 seconds to be sure the settings is updated Thread.Sleep(2000); logger.LogInfo("JavaScript file restriction removed"); } importWorker.ReportProgress(0, "Processing records..."); var rm = new RecordManager(Service); evt.Cancel = rm.ProcessRecords((EntityCollection)evt.Argument, emds, ConnectionDetail.OrganizationMajorVersion, importWorker); if (iSettings.DeactivateWebPagePlugins) { importWorker.ReportProgress(0, "Reactivating Webpage plugins steps..."); logger.LogInfo("Reactivating Webpage plugins steps"); pManager.ActivateWebpagePlugins(); logger.LogInfo("Webpage plugins steps activated"); } if (iSettings.RemoveJavaScriptFileRestriction && nManager.HasJsRestriction) { logger.LogInfo("Adding back JavaScript file restriction"); importWorker.ReportProgress(0, "Adding back JavaScript file restriction..."); nManager.AddRestriction(); logger.LogInfo("JavaScript file restriction added back"); } }; worker.RunWorkerCompleted += (s, evt) => { SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(string.Empty)); lblProgress.Text = "Records imported!"; llOpenLogFile.Visible = true; btnImportClose.Enabled = true; btnImport.Enabled = true; btnCancel.Visible = false; if (evt.Cancelled) { lblProgress.Text = "Import was canceled!"; return; } if (evt.Error != null) { MessageBox.Show(this, $"An error occured: {evt.Error.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (pbImport.IsOnError) { MessageBox.Show(this, "Import complete with errors\n\nPlease review the logs", "Information", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { MessageBox.Show(this, "Import complete", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } }; worker.ProgressChanged += (s, evt) => { if (evt.UserState is string) { lblProgress.Text = evt.UserState.ToString(); SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(evt.UserState.ToString())); } else { var progress = evt.UserState as ImportProgress; if (progress != null) { foreach (var ep in progress.Entities) { var item = lvProgress.Items.Cast <ListViewItem>().FirstOrDefault(i => i.Tag.ToString() == ep.LogicalName); if (item == null) { item = new ListViewItem($"{ep.Entity} ({ep.Count})") { Tag = ep.LogicalName }; item.SubItems.Add(ep.SuccessFirstPhase.ToString()); item.SubItems.Add(ep.ErrorFirstPhase.ToString()); item.SubItems.AddRange(new[] { "", "", "", "" }); if (ep.SuccessSecondPhase.HasValue || ep.ErrorSecondPhase.HasValue) { item.SubItems[3].Text = (ep.SuccessSecondPhase ?? 0).ToString(); item.SubItems[4].Text = (ep.ErrorSecondPhase ?? 0).ToString(); } if (ep.SuccessSetStatePhase.HasValue || ep.ErrorSetState.HasValue) { item.SubItems[5].Text = (ep.SuccessSetStatePhase ?? 0).ToString(); item.SubItems[6].Text = (ep.ErrorSetState ?? 0).ToString(); } lvProgress.Items.Add(item); } else { item.SubItems[1].Text = ep.SuccessFirstPhase.ToString(); item.SubItems[2].Text = ep.ErrorFirstPhase.ToString(); if (ep.SuccessSecondPhase.HasValue || ep.ErrorSecondPhase.HasValue) { item.SubItems[3].Text = (ep.SuccessSecondPhase ?? 0).ToString(); item.SubItems[4].Text = (ep.ErrorSecondPhase ?? 0).ToString(); } if (ep.SuccessSetStatePhase.HasValue || ep.ErrorSetState.HasValue) { item.SubItems[5].Text = (ep.SuccessSetStatePhase ?? 0).ToString(); item.SubItems[6].Text = (ep.ErrorSetState ?? 0).ToString(); } } if (ep.ErrorFirstPhase > 0 || ep.ErrorSecondPhase > 0 || ep.ErrorSetState > 0) { pbImport.IsOnError = true; } pbImport.Value = progress.Entities.Sum(ent => ent.Processed) * 100 / progress.Count; } } } }; worker.RunWorkerAsync(ec); }