private void btnRegister_Click(object sender, EventArgs e) { CrmPluginStep step = new CrmPluginStep(m_org); bool isDeploymentOfflineChecked = (chkDeploymentOffline.Enabled && chkDeploymentOffline.Checked); //The Server Deployment box should be considered "Checked" when it is enabled and checked OR when it is a service //endpoint Step (this is the case when the combo box is enabled) bool isDeploymentServerChecked = (chkDeploymentServer.Enabled && chkDeploymentServer.Checked) || cmbServiceEndpoint.Visible; #region Extract Information //Validate information if (!isDeploymentOfflineChecked && !isDeploymentServerChecked) { MessageBox.Show("At least one Step Deployment must be specified", "Step Registration", MessageBoxButtons.OK, MessageBoxIcon.Warning); chkDeploymentServer.Focus(); return; } else if (Message == null) { MessageBox.Show("Invalid Message Name specified. Please re-enter the message name", "Invalid Message Name", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtMessageName.Focus(); return; } else if (radModeAsync.Checked && !(radStagePostOperation.Checked || radStagePostOperationDeprecated.Checked)) { MessageBox.Show("Asynchronous Execution Mode requires registration in one of the Post Stages. Please change the Mode or the Stage.", "Step Registration", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else if (txtName.TextLength == 0) { MessageBox.Show("Name is a required field.", "Step Registration", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtName.Focus(); return; } else if (MessageEntity == null) { MessageBox.Show("Invalid Primary Entity or Secondary Entity specified. Please re-enter the data.", "Invalid Entity Name", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtPrimaryEntity.Focus(); return; } else if (MessageEntity.PrimaryEntity != txtPrimaryEntity.Text && txtPrimaryEntity.Text.Length > 0) { MessageBox.Show("Invalid Primary Entity specified. Please re-enter the data.", "Invalid Entity Name", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtPrimaryEntity.Focus(); return; } else if (MessageEntity.SecondaryEntity != txtSecondaryEntity.Text && txtSecondaryEntity.Text.Length > 0) { MessageBox.Show("Invalid Secondary Entity specified. Please re-enter the data.", "Invalid Entity Name", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtSecondaryEntity.Focus(); return; } else if (cmbPlugins.SelectedIndex < 0) { MessageBox.Show("Plugin was not specified. This a required field.", "Step Registration", MessageBoxButtons.OK, MessageBoxIcon.Warning); cmbPlugins.Focus(); return; } else if (cmbUsers.SelectedIndex < 0) { MessageBox.Show("User was not specified. This a required field.", "Step Registration", MessageBoxButtons.OK, MessageBoxIcon.Warning); cmbUsers.Focus(); return; } else if (txtName.TextLength == 0) { txtName.Text = GenerateDescription(); } else if (isDeploymentOfflineChecked && txtSecureConfig.TextLength != 0 && txtSecureConfig.Text.Trim().Length != 0) { MessageBox.Show(this, "Secure Configuration is not supported for Steps deployed Offline.", "Registration", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } CrmPlugin plugin = (CrmPlugin)cmbPlugins.SelectedItem; if (cmbServiceEndpoint.Visible) { if ((radModeSync.Checked)) { MessageBox.Show("Only asynchronous steps are supported for Service Endpoint plug-ins.", "Step Registration", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else if (cmbServiceEndpoint.SelectedIndex < 0) { MessageBox.Show("Service Endpoint must be selected for Service Endpoint plug-ins.", "Step Registration", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } step.MessageId = Message.MessageId; step.MessageEntityId = MessageEntity.MessageEntityId; step.AssemblyId = plugin.AssemblyId; step.FilteringAttributes = crmFilteringAttributes.Attributes; step.PluginId = plugin.PluginId; step.ImpersonatingUserId = ((CrmUser)cmbUsers.SelectedItem).UserId; step.Name = txtName.Text; step.UnsecureConfiguration = txtUnsecureConfiguration.Text; step.Description = txtDescription.Text; if (txtSecureConfig.Visible) { step.SecureConfiguration = txtSecureConfig.Text; } if (cmbServiceEndpoint.Visible) { step.ServiceBusConfigurationId = ((CrmServiceEndpoint)cmbServiceEndpoint.SelectedItem).ServiceEndpointId; } else { step.ServiceBusConfigurationId = Guid.Empty; } step.Rank = int.Parse(txtRank.Text); step.Mode = (radModeAsync.Checked ? CrmPluginStepMode.Asynchronous : CrmPluginStepMode.Synchronous); if (radStagePreValidation.Checked) { step.Stage = CrmPluginStepStage.PreValidation; } else if (radStagePreOperation.Checked) { step.Stage = CrmPluginStepStage.PreOperation; } else if (radStagePostOperation.Checked) { step.Stage = CrmPluginStepStage.PostOperation; } else if (radStagePostOperationDeprecated.Checked) { step.Stage = CrmPluginStepStage.PostOperationDeprecated; } else { throw new NotImplementedException("Unkown Plug-in Stage checked"); } if (null != m_currentStep) { step.Enabled = m_currentStep.Enabled; } if (isDeploymentServerChecked && isDeploymentOfflineChecked) { step.Deployment = CrmPluginStepDeployment.Both; } else if (isDeploymentOfflineChecked) { step.Deployment = CrmPluginStepDeployment.OfflineOnly; } else { step.Deployment = CrmPluginStepDeployment.ServerOnly; } if (grpInvocation.Enabled) { step.InvocationSource = (radInvocationParent.Checked ? CrmPluginStepInvocationSource.Parent : CrmPluginStepInvocationSource.Child); } else { step.InvocationSource = null; } if (step.Mode == CrmPluginStepMode.Asynchronous) { step.DeleteAsyncOperationIfSuccessful = chkDeleteAsyncOperationIfSuccessful.Checked; } else { step.DeleteAsyncOperationIfSuccessful = false; } if (plugin.IsProfilerPlugin) { //step.ProfilerStepId = step.StepId; //step.UnsecureConfiguration = OrganizationHelper.UpdateWithStandaloneConfiguration(step).ToString(); } else if (null != m_currentStep) { step.ProfilerOriginalStepId = m_currentStep.ProfilerOriginalStepId; step.ProfilerStepId = m_currentStep.ProfilerStepId; } #endregion Extract Information #region Register the Step bool rankChanged = false; try { if (m_currentStep != null) { Guid?secureConfigurationId = m_currentStep.SecureConfigurationId; if (m_currentStep.SecureConfigurationRecordIdInvalid) { if (m_secureConfigurationIdIsInvalid) { secureConfigurationId = null; } else { secureConfigurationId = Guid.Empty; } } // If the message has changed, the images may need to change as well List <CrmPluginImage> updateImages = null; if (m_currentStep.MessageId != step.MessageId) { // Add the images for the current step to the list updateImages = new List <CrmPluginImage>(m_currentStep.Images.Count); updateImages.AddRange(m_currentStep.Images.Values); } step.StepId = m_currentStep.StepId; if (!RegistrationHelper.UpdateStep(m_org, step, secureConfigurationId, updateImages)) { DialogResult = System.Windows.Forms.DialogResult.None; return; } ////Refresh the profiler step to have the same settings //if (step.IsProfiled) //{ // OrganizationHelper.RefreshProfilerStep(step); //} rankChanged = (m_currentStep.Rank != step.Rank); m_currentStep.SecureConfigurationRecordIdInvalid = m_secureConfigurationIdIsInvalid; m_currentStep.Deployment = step.Deployment; m_currentStep.Name = step.Name; m_currentStep.ImpersonatingUserId = step.ImpersonatingUserId; m_currentStep.InvocationSource = step.InvocationSource; m_currentStep.MessageEntityId = step.MessageEntityId; m_currentStep.MessageId = step.MessageId; m_currentStep.FilteringAttributes = step.FilteringAttributes; m_currentStep.Mode = step.Mode; m_currentStep.Rank = step.Rank; m_currentStep.DeleteAsyncOperationIfSuccessful = step.DeleteAsyncOperationIfSuccessful; if (txtSecureConfig.Visible) { m_currentStep.SecureConfiguration = step.SecureConfiguration; m_currentStep.SecureConfigurationId = step.SecureConfigurationId; } m_currentStep.Stage = step.Stage; m_currentStep.UnsecureConfiguration = step.UnsecureConfiguration; m_currentStep.Description = step.Description; m_currentStep.ProfilerStepId = step.ProfilerStepId; List <ICrmEntity> stepList = new List <ICrmEntity>(new ICrmEntity[] { step }); OrganizationHelper.UpdateDates(m_org, stepList); if (m_currentStep.PluginId != step.PluginId) { m_orgControl.RemoveStep(step.NodeId); m_org.Assemblies[m_currentStep.AssemblyId][m_currentStep.PluginId].RemoveStep(step.StepId); m_currentStep.AssemblyId = step.AssemblyId; m_currentStep.PluginId = step.PluginId; m_org.Assemblies[step.AssemblyId][step.PluginId].AddStep(step); m_orgControl.AddStep(step); } else if (m_currentStep.ServiceBusConfigurationId != step.ServiceBusConfigurationId) { m_orgControl.RemoveStep(step.NodeId); m_org.Assemblies[m_currentStep.AssemblyId][m_currentStep.PluginId].RemoveStep(step.StepId); m_currentStep.ServiceBusConfigurationId = step.ServiceBusConfigurationId; m_org.Assemblies[step.AssemblyId][step.PluginId].AddStep(step); m_orgControl.AddStep(step); } else { m_orgControl.RefreshStep(m_currentStep); } step = m_currentStep; } else { step.StepId = RegistrationHelper.RegisterStep(m_org, step); List <ICrmEntity> stepList = new List <ICrmEntity>(new ICrmEntity[] { step }); OrganizationHelper.UpdateDates(m_org, stepList); plugin.AddStep(step); m_orgControl.AddStep(step); OrganizationHelper.RefreshStep(m_org, step); } } catch (Exception ex) { ErrorMessageForm.ShowErrorMessageBox(this, "Error occurred while registering the step", "Registration Error", ex); return; } #endregion Register the Step DialogResult = DialogResult.OK; Close(); }
public static bool UpdateStep(CrmOrganization org, CrmPluginStep step, Guid?origSecureConfigId, IList <CrmPluginImage> updateImages) { if (org == null) { throw new ArgumentNullException("org"); } else if (step == null) { throw new ArgumentNullException("step"); } Dictionary <string, object> entityList = step.GenerateCrmEntities(); SdkMessageProcessingStep sdkStep = (SdkMessageProcessingStep)entityList[SdkMessageProcessingStep.EntityLogicalName]; // Loop through each image and set the new message property List <SdkMessageProcessingStepImage> sdkImages = null; if (null != updateImages) { // Ensure that the given message supports images CrmMessage message = org.Messages[step.MessageId]; if (0 == message.ImageMessagePropertyNames.Count && step.Images.Count > 0) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The step has images registered, but the \"{0}\" message doesn't support images.{1}In order to change the message to \"{0}\", delete the existing images.", message.Name, Environment.NewLine)); } // Loop through the existing images and update their message property name values sdkImages = new List <SdkMessageProcessingStepImage>(updateImages.Count); foreach (CrmPluginImage image in updateImages) { // Set the message property name for each of the images string propertyName = MessagePropertyNameForm.SelectMessagePropertyName(message); if (string.IsNullOrWhiteSpace(propertyName)) { return(false); } else if (string.Equals(image.MessagePropertyName, propertyName, StringComparison.Ordinal)) { continue; } // Create the entity to update the value SdkMessageProcessingStepImage sdkImage = new SdkMessageProcessingStepImage(); sdkImage.Id = image.ImageId; sdkImage.MessagePropertyName = propertyName; sdkImage.EntityState = EntityState.Changed; sdkImages.Add(sdkImage); } } //This is a sanity check. The UI won't allow a user to set the secure configuration. if (org.SecureConfigurationPermissionDenied) { sdkStep.Attributes.Remove("sdkmessageprocessingstepsecureconfigid"); sdkStep.RelatedEntities.Clear(); origSecureConfigId = null; } else if (entityList.ContainsKey(Entities.SdkMessageProcessingStepSecureConfig.EntityLogicalName)) { if (null == origSecureConfigId) { entityList.Remove(Entities.SdkMessageProcessingStepSecureConfig.EntityLogicalName); } else { SdkMessageProcessingStepSecureConfig sdkSecureConfig = (SdkMessageProcessingStepSecureConfig)entityList[SdkMessageProcessingStepSecureConfig.EntityLogicalName]; Guid secureConfigId; EntityState secureConfigState; if (step.SecureConfigurationId == origSecureConfigId && origSecureConfigId.GetValueOrDefault() != Guid.Empty) { //Set the ID of the secure configuration to be the secureConfigId = origSecureConfigId.GetValueOrDefault(); secureConfigState = EntityState.Changed; //Set the original secure config id so that the current id is not deleted sdkStep.SdkMessageProcessingStepSecureConfigId = new EntityReference(SdkMessageProcessingStepSecureConfig.EntityLogicalName, secureConfigId); } else { secureConfigId = Guid.NewGuid(); secureConfigState = EntityState.Created; } //Set the configuration id for the step step.SecureConfigurationId = secureConfigId; //Populate the secure configuration object and add it to the related entities sdkSecureConfig.SdkMessageProcessingStepSecureConfigId = secureConfigId; sdkSecureConfig.EntityState = secureConfigState; //Update the related entities sdkStep.sdkmessageprocessingstepsecureconfigid_sdkmessageprocessingstep = sdkSecureConfig; //Reset the original secure configuration origSecureConfigId = null; } } else if (null != origSecureConfigId) { // To null out if it was set before sdkStep.SdkMessageProcessingStepSecureConfigId = null; step.SecureConfigurationId = Guid.Empty; if (Guid.Empty == origSecureConfigId) { origSecureConfigId = null; } } // If the images need to be updated, there are two possible scenarios: // 1) The step is profiled -- The parent of the image is not the step that is currently being updated // but rather the profiler step itself. In order to avoid changing this, there will have to be two SDK // operations (update the step and update the images). Otherwise, the next time the profiled step executes, // the images won't be present. // 2) The step is not profiled -- The image can be added to the related entities because the parent step is the // current step being updated. if (null != sdkImages && sdkImages.Count > 0) { if (!step.IsProfiled || step.ProfilerStepId == step.StepId) { sdkStep.sdkmessageprocessingstepid_sdkmessageprocessingstepimage = sdkImages; } } //Update the step org.OrganizationService.Update(sdkStep); if (step.IsProfiled && null != sdkImages && sdkImages.Count > 0) { // Update the Profiler step with the new property values as a single transaction to minimize the // possibility of data corruption. SdkMessageProcessingStep profilerStep = new SdkMessageProcessingStep(); profilerStep.Id = step.ProfilerStepId.GetValueOrDefault(); profilerStep.sdkmessageprocessingstepid_sdkmessageprocessingstepimage = sdkImages; org.OrganizationService.Update(profilerStep); } // Refresh the objects so that the caller has up-to-date data OrganizationHelper.RefreshStep(org, step); if (null != updateImages) { foreach (CrmPluginImage image in updateImages) { OrganizationHelper.RefreshImage(org, image, step); } } // Delete the orphaned Secure config when nulling out the value on the step if (null != origSecureConfigId) { org.OrganizationService.Delete(SdkMessageProcessingStepSecureConfig.EntityLogicalName, origSecureConfigId.GetValueOrDefault()); } return(true); }