public void DeploymentDeploySolutionTest() { var altConnection = GetAltSavedXrmRecordConfiguration(); var sourceSolution = ReCreateTestSolution(); var request = new DeploySolutionRequest(); request.SourceConnection = GetSavedXrmRecordConfiguration(); request.TargetConnection = GetAltSavedXrmRecordConfiguration(); request.Solution = sourceSolution.ToLookup(); request.ThisReleaseVersion = "3.0.0.0"; request.SetVersionPostRelease = "4.0.0.0"; var altService = new XrmRecordService(altConnection); var targetSolution = altService.GetFirst(Entities.solution, Fields.solution_.uniquename, sourceSolution.GetStringField(Fields.solution_.uniquename)); if (targetSolution != null) { altService.Delete(targetSolution); } var createApplication = CreateAndLoadTestApplication <DeploySolutionModule>(); var response = createApplication.NavigateAndProcessDialog <DeploySolutionModule, DeploySolutionDialog, DeploySolutionResponse>(request); Assert.IsFalse(response.HasError); targetSolution = altService.GetFirst(Entities.solution, Fields.solution_.uniquename, sourceSolution.GetStringField(Fields.solution_.uniquename)); Assert.IsTrue(targetSolution != null); Assert.AreEqual("3.0.0.0", targetSolution.GetStringField(Fields.solution_.version)); sourceSolution = XrmRecordService.Get(sourceSolution.Type, sourceSolution.Id); Assert.AreEqual("4.0.0.0", sourceSolution.GetStringField(Fields.solution_.version)); }
protected override string GetUrl() { var solution = XrmRecordService.GetFirst(Entities.solution, Fields.solution_.uniquename, "default"); if (solution == null) { throw new NullReferenceException($"Could Not Find Solution named 'default'"); } var url = XrmRecordService.WebUrl; var solutionUrl = string.Format("{0}/tools/solution/edit.aspx?id={1}", url, solution.Id.ToString()); return(solutionUrl); }
public void DeleteTestNewLookupPublisher() { while (true) { var test = XrmRecordService.GetFirst(JosephM.Xrm.Schema.Entities.publisher, JosephM.Xrm.Schema.Fields.publisher_.uniquename, "TESTNEWLOOKUPPUBLISHER"); if (test != null) { XrmRecordService.Delete(test); } else { break; } } }
public void DeleteTestNewLookupSolution() { while (true) { var test = XrmRecordService.GetFirst(JosephM.Xrm.Schema.Entities.solution, JosephM.Xrm.Schema.Fields.solution_.uniquename, "TESTNEWLOOKUPSOLUTION"); if (test != null) { XrmRecordService.Delete(test); } else { break; } } }
public void RecordExtractXrmCreateDocumentTest() { PrepareTests(); var testReportRecord = XrmRecordService.GetFirst(Entities.contact); //script out a document from fake data var recordService = FakeRecordService.Get(); const string type = FakeConstants.RecordType; var request = new RecordExtractRequest(); request.SaveToFolder = new Folder(TestingFolder); request.RecordType = new RecordType(type, recordService.GetDisplayName(type)); request.RecordLookup = new Lookup(testReportRecord.Type, testReportRecord.Id, "Test Report"); var response = new RecordExtractResponse(); XrmRecordExtractService.ExecuteExtention(request, response, CreateServiceRequestController()); }
public IRecord ReCreateTestSolution() { var testSolution = XrmRecordService.GetFirst(JosephM.Xrm.Schema.Entities.solution, JosephM.Xrm.Schema.Fields.solution_.uniquename, "TESTSCRIPTSOLUTION"); if (testSolution != null) { XrmRecordService.Delete(testSolution); } var publisher = XrmRecordService.GetFirst(JosephM.Xrm.Schema.Entities.publisher, JosephM.Xrm.Schema.Fields.publisher_.uniquename, "josephmcgregor"); testSolution = XrmRecordService.NewRecord(JosephM.Xrm.Schema.Entities.solution); testSolution.SetField(JosephM.Xrm.Schema.Fields.solution_.publisherid, publisher.ToLookup(), XrmRecordService); testSolution.SetField(JosephM.Xrm.Schema.Fields.solution_.uniquename, "TESTSCRIPTSOLUTION", XrmRecordService); testSolution.SetField(JosephM.Xrm.Schema.Fields.solution_.friendlyname, "TESTSCRIPTSOLUTION", XrmRecordService); testSolution.SetField(JosephM.Xrm.Schema.Fields.solution_.version, "1.0.0.0", XrmRecordService); testSolution.Id = XrmRecordService.Create(testSolution); return(testSolution); }
public void VsixAddPortalCodeTest() { RecreatePortalData(createSecondDuplicateSite: true); var app = CreateAndLoadTestApplication <AddPortalCodeModule>(); var fakeProjectName = "FakeProjectName"; var directoryInfo = Directory.CreateDirectory(Path.Combine(VisualStudioService.SolutionDirectory, fakeProjectName)); VisualStudioService.SetSelectedItem(new FakeVisualStudioSolutionFolder(directoryInfo.FullName)); var websiteName = "Fake Site 1"; var webSite = XrmRecordService.GetFirst(Entities.adx_website, Fields.adx_website_.adx_name, websiteName); var request = new AddPortalCodeRequest { WebSite = XrmRecordService.ToLookup(webSite), ExportWhereFieldEmpty = true, CreateFolderForWebsiteName = true }; var dialog = app.NavigateToDialog <AddPortalCodeModule, AddPortalCodeDialog>(); var entryForm = app.GetSubObjectEntryViewModel(dialog); entryForm.GetLookupFieldFieldViewModel(nameof(AddPortalCodeRequest.WebSite)).SetValue(entryForm.GetLookupFieldFieldViewModel(nameof(AddPortalCodeRequest.WebSite)).ItemsSourceAsync.First(r => r.Record != null).Record); entryForm.GetBooleanFieldFieldViewModel(nameof(AddPortalCodeRequest.ExportWhereFieldEmpty)).Value = true; entryForm.GetBooleanFieldFieldViewModel(nameof(AddPortalCodeRequest.CreateFolderForWebsiteName)).Value = true; var section = entryForm.GetFieldSection(AddPortalCodeRequest.Sections.RecordsToInclude); var func = section.CustomFunctions.First(c => c.Id == "SELECTALL"); func.Invoke(); Assert.IsTrue(entryForm.GetEnumerableFieldViewModel(nameof(AddPortalCodeRequest.RecordsToExport)).GridRecords .All(r => r.GetBooleanFieldFieldViewModel(nameof(AddPortalCodeRequest.PortalRecordsToExport.Selected)).Value ?? false)); var webTemplateRow = entryForm.GetEnumerableFieldViewModel(nameof(AddPortalCodeRequest.RecordsToExport)) .GridRecords .First(gr => gr.GetRecordTypeFieldViewModel(nameof(AddPortalCodeRequest.PortalRecordsToExport.RecordType)).Value.Key == Entities.adx_webtemplate); webTemplateRow.GetBooleanFieldFieldViewModel(nameof(AddPortalCodeRequest.PortalRecordsToExport.IncludeAll)).Value = false; //this now auto runs when the flag above iunchecked //webTemplateRow.GetEnumerableFieldViewModel(nameof(AddPortalCodeRequest.PortalRecordsToExport.RecordsToInclude)).BulkAddButton.Invoke(); var templateRecordSelectionForm = entryForm.ChildForms.First() as MultiSelectDialogViewModel <PicklistOption>; templateRecordSelectionForm.ItemsSource.First().Select = true; templateRecordSelectionForm.ItemsSource.Last().Select = true; templateRecordSelectionForm.ApplyButtonViewModel.Invoke(); Assert.IsFalse(entryForm.ChildForms.Any()); Assert.IsTrue(entryForm.Validate()); entryForm.SaveButtonViewModel.Invoke(); var responseViewModel = app.GetCompletionViewModel(dialog); var response = responseViewModel.GetObject() as AddPortalCodeResponse; Assert.IsFalse(response.HasError); var rootFolder = Path.Combine(directoryInfo.FullName, websiteName); foreach (var typesFolder in new DirectoryInfo(rootFolder).GetDirectories()) { var fileCountInDirectory = typesFolder.GetFiles().Count(); var typeLabel = typesFolder.Name; var type = XrmRecordService.GetAllRecordTypes().First(rt => XrmRecordService.GetDisplayName(rt) == typeLabel); var recordsOfType = XrmRecordService.RetrieveAll(type, null); if (type == Entities.adx_webpage) { //web pages have a parent and child where onluy the ch9ild is exported // (multi language not implemented) // + each has html, css & javascript Assert.AreEqual((recordsOfType.Count() / 4) * 3, fileCountInDirectory); } else if (type == Entities.adx_webtemplate) { Assert.AreEqual(2, fileCountInDirectory); } else { Assert.AreEqual(recordsOfType.Count() / 2, fileCountInDirectory); } } }
public override void ExecuteExtention(DeployWebResourceRequest request, DeployWebResourceResponse response, ServiceRequestController controller) { var records = new List <IRecord>(); var publishIds = new List <string>(); var totalTasks = request.Files.Count() + 1; var tasksCompleted = 0; foreach (var file in request.Files) { var fileInfo = new FileInfo(file); var fileName = fileInfo.Name; controller.UpdateProgress(++tasksCompleted, totalTasks, "Deploying " + fileName); var responseItem = new DeployWebResourceResponseItem(); responseItem.Name = fileName; response.AddResponseItem(responseItem); try { var content = File.ReadAllBytes(file); var contentString = Convert.ToBase64String(content); //okay lets allow match on either name or display name var match = Service.GetFirst(Entities.webresource, Fields.webresource_.name, fileName); if (match == null) { match = Service.GetFirst(Entities.webresource, Fields.webresource_.displayname, fileName); } if (match != null) { if (match.GetStringField(Fields.webresource_.content) != contentString) { match.SetField(Fields.webresource_.content, contentString, Service); Service.Update(match, new[] { Fields.webresource_.content }); publishIds.Add(match.Id); responseItem.Updated = true; } } else { var record = Service.NewRecord(Entities.webresource); record.SetField(Fields.webresource_.name, fileInfo.Name, Service); record.SetField(Fields.webresource_.displayname, fileInfo.Name, Service); record.SetField(Fields.webresource_.content, Convert.ToBase64String(content), Service); record.SetField(Fields.webresource_.webresourcetype, GetWebResourceType(fileInfo.Extension), Service); record.Id = Service.Create(record); publishIds.Add(record.Id); responseItem.Created = true; } } catch (Exception ex) { responseItem.Exception = ex; } } if (publishIds.Any()) { controller.UpdateProgress(totalTasks, totalTasks, "Publishing Files"); var xml = new StringBuilder(); xml.Append("<importexportxml><webresources>"); foreach (var id in publishIds) { xml.Append("<webresource>" + id + "</webresource>"); } xml.Append("</webresources></importexportxml>"); Service.Publish(xml.ToString()); } //add plugin assembly to the solution var componentType = OptionSets.SolutionComponent.ObjectTypeCode.WebResource; if (PackageSettings.AddToSolution) { Service.AddSolutionComponents(PackageSettings.Solution.Id, componentType, publishIds); } }
private void Load(string assemblyName) { var assemblyRecord = XrmRecordService.GetFirst(Entities.pluginassembly, Fields.pluginassembly_.name, assemblyName); if (assemblyRecord == null) { throw new NullReferenceException("Assembly Not Deployed"); } var pluginTypes = XrmRecordService.RetrieveAllAndClauses(Entities.plugintype, new[] { new Condition(Fields.plugintype_.pluginassemblyid, ConditionType.Equal, assemblyRecord.Id) }); if (!pluginTypes.Any()) { throw new NullReferenceException("Not Plugin Types Deployed For Assembly"); } SdkMessageStepsPre = XrmRecordService.RetrieveAllOrClauses(Entities.sdkmessageprocessingstep, pluginTypes.Select( pt => new Condition(Fields.sdkmessageprocessingstep_.plugintypeid, ConditionType.Equal, pt.Id))); var sdkMessageStepsWithFilter = SdkMessageStepsPre .Where(sms => sms.GetField(Fields.sdkmessageprocessingstep_.sdkmessagefilterid) != null); var filters = !sdkMessageStepsWithFilter.Any() ? new IRecord[0] : XrmRecordService.RetrieveAllOrClauses(Entities.sdkmessagefilter, sdkMessageStepsWithFilter.Select( sms => new Condition(Fields.sdkmessagefilter_.sdkmessagefilterid, ConditionType.Equal, sms.GetLookupId(Fields.sdkmessageprocessingstep_.sdkmessagefilterid)))); var preImages = SdkMessageStepsPre.Any() ? XrmRecordService.RetrieveAllOrClauses(Entities.sdkmessageprocessingstepimage, SdkMessageStepsPre.Select(m => new Condition(Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid, ConditionType.Equal, m.Id))) .Where(i => i.GetOptionKey(Fields.sdkmessageprocessingstepimage_.imagetype) == OptionSets.SdkMessageProcessingStepImage.ImageType.PreImage.ToString()) .GroupBy(i => i.GetLookupField(Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid)) .Where(g => g.Key != null && g.Key.Id != null) .ToDictionary(i => i.Key.Id, g => g.First()) : new Dictionary <string, IRecord>(); _entryObject = new PluginTriggers(); var triggers = new List <PluginTrigger>(); EntryObject.Triggers = triggers; EntryObject.Assembly = assemblyRecord.ToLookup(); foreach (var item in SdkMessageStepsPre) { var filterId = item.GetLookupId(Fields.sdkmessageprocessingstep_.sdkmessagefilterid); var matchingFilters = filters.Where(f => f.Id == filterId); var filter = matchingFilters.Any() ? matchingFilters.First() : null; var recordType = filter == null ? null : filter.GetStringField(Fields.sdkmessagefilter_.primaryobjecttypecode); RecordType recordTypeObj = null; try { recordTypeObj = new RecordType(recordType, XrmRecordService.GetDisplayName(recordType)); } catch (Exception) { } var rank = item.GetIntegerField(Fields.sdkmessageprocessingstep_.rank); var name = item.GetStringField(Fields.sdkmessageprocessingstep_.name); var stage = item.GetOptionKey(Fields.sdkmessageprocessingstep_.stage); var mode = item.GetOptionKey(Fields.sdkmessageprocessingstep_.mode); var filteringAttributesString = item.GetStringField(Fields.sdkmessageprocessingstep_.filteringattributes); var trigger = new PluginTrigger(); //load trigger details trigger.Id = item.Id; //for some unknown reason this field was setting the target type ot sdkmessage filter //despite the target being plugin type so I had to implement this to correct the type //the name is popuated after the loop trigger.Message = filter == null ? null : filter.GetLookupField(Fields.sdkmessagefilter_.sdkmessageid); item.SetField(Fields.sdkmessageprocessingstep_.plugintypeid, new Lookup(Entities.plugintype, item.GetLookupId(Fields.sdkmessageprocessingstep_.plugintypeid), null), XrmRecordService); trigger.Plugin = item.GetLookupField(Fields.sdkmessageprocessingstep_.plugintypeid); trigger.RecordType = recordTypeObj; trigger.Stage = stage.ParseEnum <PluginTrigger.PluginStage>(); trigger.Mode = mode.ParseEnum <PluginTrigger.PluginMode>(); trigger.Rank = rank; trigger.FilteringFields = filteringAttributesString == null ? new RecordField[0] : filteringAttributesString.Split(',') .Select(s => s.Trim()) .Where(s => !string.IsNullOrWhiteSpace(s)) .Select(s => new RecordField(s, s)) .ToArray(); trigger.SpecificUserContext = item.GetLookupField(Fields.sdkmessageprocessingstep_.impersonatinguserid); //load image details if there is one if (trigger.Id != null) { if (!preImages.ContainsKey(item.Id)) { trigger.PreImageAllFields = false; } else { var preImage = preImages[item.Id]; var attributes = preImage.GetStringField(Fields.sdkmessageprocessingstepimage_.attributes); trigger.PreImageAllFields = string.IsNullOrWhiteSpace(attributes); trigger.PreImageFields = attributes == null ? new RecordField[0] : attributes .Split(',') .Select(s => s.Trim()) .Where(s => !string.IsNullOrWhiteSpace(s)) .Select(s => new RecordField(s, s)) .ToArray(); trigger.PreImageName = preImage.GetStringField(Fields.sdkmessageprocessingstepimage_.entityalias); trigger.PreImageId = preImage.Id; } } triggers.Add(trigger); } //since I had to correct the target type for this fieldsw lookup need to populate the name if (triggers.Any()) { XrmRecordService.PopulateLookups(new Dictionary <string, List <Lookup> >() { { Fields.sdkmessageprocessingstep_.plugintypeid, triggers.Select(t => t.Plugin).ToList() } }, null); } }
public void VsixManagePluginTriggersTest() { var packageSettings = GetTestPackageSettings(); DeployAssembly(packageSettings); var assemblyRecord = GetTestPluginAssemblyRecords().First(); DeletePluginTriggers(assemblyRecord); //add one update trigger RunDialogAndAddMessage("Update"); //verify trigger created var triggers = GetPluginTriggers(assemblyRecord); Assert.AreEqual(1, triggers.Count()); Assert.IsTrue(triggers.First().GetBoolField(Fields.sdkmessageprocessingstep_.asyncautodelete)); Assert.IsNull(triggers.First().GetStringField(Fields.sdkmessageprocessingstep_.filteringattributes)); Assert.IsNull(triggers.First().GetStringField(Fields.sdkmessageprocessingstep_.impersonatinguserid)); //verify preimage created for update with all fields var image = XrmRecordService.GetFirst(Entities.sdkmessageprocessingstepimage, Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid, triggers.First().Id); Assert.IsNotNull(image); Assert.IsNull(image.GetStringField(Fields.sdkmessageprocessingstepimage_.attributes)); Assert.AreEqual("PreImage", image.GetStringField(Fields.sdkmessageprocessingstepimage_.entityalias)); //add one create trigger RunDialogAndAddMessage("Create"); //verify created triggers = GetPluginTriggers(assemblyRecord); Assert.AreEqual(2, triggers.Count()); //delete a trigger var dialog = new ManagePluginTriggersDialog(CreateDialogController(), new FakeVisualStudioService(), XrmRecordService, packageSettings); dialog.Controller.BeginDialog(); var entryViewModel = (ObjectEntryViewModel)dialog.Controller.UiItems.First(); var triggersSubGrid = entryViewModel.SubGrids.First(); triggersSubGrid.GridRecords.First().DeleteRow(); Assert.IsTrue(entryViewModel.Validate()); entryViewModel.OnSave(); //verify deleted triggers = GetPluginTriggers(assemblyRecord); Assert.AreEqual(1, triggers.Count()); //add 2 update triggers RunDialogAndAddMessage("Update"); RunDialogAndAddMessage("Update"); triggers = GetPluginTriggers(assemblyRecord); Assert.AreEqual(3, triggers.Count()); //okay now lets inspect and adjust the filtering attributes and preimages and impersonating user in one of the update messages dialog = new ManagePluginTriggersDialog(CreateDialogController(), new FakeVisualStudioService(), XrmRecordService, packageSettings); dialog.Controller.BeginDialog(); entryViewModel = (ObjectEntryViewModel)dialog.Controller.UiItems.First(); triggersSubGrid = entryViewModel.SubGrids.First(); var updateRows = triggersSubGrid.GridRecords.Where(r => r.GetLookupFieldFieldViewModel(nameof(PluginTrigger.Message)).Value.Name == "Update"); var letsAdjustThisOne = updateRows.First(); //set no not all preimage fields letsAdjustThisOne.GetBooleanFieldFieldViewModel(nameof(PluginTrigger.PreImageAllFields)).Value = false; //set some arbitrary other image name letsAdjustThisOne.GetStringFieldFieldViewModel(nameof(PluginTrigger.PreImageName)).Value = "FooOthername"; //set some specific fields in the preimage var preImageFieldsField = letsAdjustThisOne.GetFieldViewModel <RecordFieldMultiSelectFieldViewModel>(nameof(PluginTrigger.PreImageFields)); SelectItems(preImageFieldsField, 1, 3); //set some specific filtering attributes var filteringAttributesField = letsAdjustThisOne.GetFieldViewModel <RecordFieldMultiSelectFieldViewModel>(nameof(PluginTrigger.FilteringFields)); SelectItems(filteringAttributesField, 1, 3); //set impersonating user var impersonatingUserField = letsAdjustThisOne.GetLookupFieldFieldViewModel(nameof(PluginTrigger.SpecificUserContext)); impersonatingUserField.SelectedItem = impersonatingUserField.ItemsSource.First(p => p.Record?.Id == CurrentUserId.ToString()); //save Assert.IsTrue(entryViewModel.Validate()); entryViewModel.OnSave(); //verify still 3 triggers triggers = GetPluginTriggers(assemblyRecord); Assert.AreEqual(3, triggers.Count()); //get the record we updated var updatedTriggerMatches = triggers.Where(t => t.GetStringField(Fields.sdkmessageprocessingstep_.filteringattributes) != null); Assert.AreEqual(1, updatedTriggerMatches.Count()); var updatedTrigger = updatedTriggerMatches.First(); //verify the filtering and image fields we set got saved correctly Assert.IsNotNull(updatedTrigger.GetStringField(Fields.sdkmessageprocessingstep_.filteringattributes)); Assert.AreEqual(CurrentUserId.ToString(), updatedTrigger.GetLookupId(Fields.sdkmessageprocessingstep_.impersonatinguserid)); image = XrmRecordService.GetFirst(Entities.sdkmessageprocessingstepimage, Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid, updatedTrigger.Id); Assert.IsNotNull(image); Assert.IsNotNull(image.GetStringField(Fields.sdkmessageprocessingstepimage_.attributes)); Assert.AreEqual("FooOthername", image.GetStringField(Fields.sdkmessageprocessingstepimage_.entityalias)); //lets just verify if we go through te dialog without touching the record we adjusted that it is still the same after the save dialog = new ManagePluginTriggersDialog(CreateDialogController(), new FakeVisualStudioService(), XrmRecordService, packageSettings); dialog.Controller.BeginDialog(); entryViewModel = (ObjectEntryViewModel)dialog.Controller.UiItems.First(); Assert.IsTrue(entryViewModel.Validate()); entryViewModel.OnSave(); updatedTrigger = XrmRecordService.Get(updatedTrigger.Type, updatedTrigger.Id); Assert.IsNotNull(updatedTrigger.GetStringField(Fields.sdkmessageprocessingstep_.filteringattributes)); Assert.AreEqual(CurrentUserId.ToString(), updatedTrigger.GetLookupId(Fields.sdkmessageprocessingstep_.impersonatinguserid)); XrmRecordService.GetFirst(Entities.sdkmessageprocessingstepimage, Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid, triggers.First().Id); Assert.IsNotNull(image); Assert.IsNotNull(image.GetStringField(Fields.sdkmessageprocessingstepimage_.attributes)); Assert.AreEqual("FooOthername", image.GetStringField(Fields.sdkmessageprocessingstepimage_.entityalias)); //now lets verify deletion of an image if changed to not have one (image deleted) as well as clear impersonating user dialog = new ManagePluginTriggersDialog(CreateDialogController(), new FakeVisualStudioService(), XrmRecordService, packageSettings); dialog.Controller.BeginDialog(); entryViewModel = (ObjectEntryViewModel)dialog.Controller.UiItems.First(); triggersSubGrid = entryViewModel.SubGrids.First(); letsAdjustThisOne = triggersSubGrid.GridRecords.First(r => r.GetRecord().GetStringField(nameof(PluginTrigger.Id)) == updatedTrigger.Id); impersonatingUserField = letsAdjustThisOne.GetLookupFieldFieldViewModel(nameof(PluginTrigger.SpecificUserContext)); impersonatingUserField.SelectedItem = impersonatingUserField.ItemsSource.First(p => p.Record == null); //set no not all preimage fields letsAdjustThisOne.GetBooleanFieldFieldViewModel(nameof(PluginTrigger.PreImageAllFields)).Value = false; //set no fields on the preimage preImageFieldsField = letsAdjustThisOne.GetFieldViewModel <RecordFieldMultiSelectFieldViewModel>(nameof(PluginTrigger.PreImageFields)); DeselectAll(preImageFieldsField); //save Assert.IsTrue(entryViewModel.Validate()); entryViewModel.OnSave(); //verify now no impersonation updatedTrigger = XrmRecordService.Get(updatedTrigger.Type, updatedTrigger.Id); Assert.IsNull(updatedTrigger.GetLookupId(Fields.sdkmessageprocessingstep_.impersonatinguserid)); //verify no image image = XrmRecordService.GetFirst(Entities.sdkmessageprocessingstepimage, Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid, updatedTrigger.Id); Assert.IsNull(image); //lets just verify if we go through te dialog without touching the record still doesn't have one dialog = new ManagePluginTriggersDialog(CreateDialogController(), new FakeVisualStudioService(), XrmRecordService, packageSettings); dialog.Controller.BeginDialog(); entryViewModel = (ObjectEntryViewModel)dialog.Controller.UiItems.First(); Assert.IsTrue(entryViewModel.Validate()); entryViewModel.OnSave(); //verify still no impersonation updatedTrigger = XrmRecordService.Get(updatedTrigger.Type, updatedTrigger.Id); Assert.IsNull(updatedTrigger.GetLookupId(Fields.sdkmessageprocessingstep_.impersonatinguserid)); //verify still no image image = XrmRecordService.GetFirst(Entities.sdkmessageprocessingstepimage, Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid, updatedTrigger.Id); Assert.IsNull(image); //add the image again dialog = new ManagePluginTriggersDialog(CreateDialogController(), new FakeVisualStudioService(), XrmRecordService, packageSettings); dialog.Controller.BeginDialog(); entryViewModel = (ObjectEntryViewModel)dialog.Controller.UiItems.First(); triggersSubGrid = entryViewModel.SubGrids.First(); letsAdjustThisOne = triggersSubGrid.GridRecords.First(r => r.GetRecord().GetStringField(nameof(PluginTrigger.Id)) == updatedTrigger.Id); //set no not all preimage fields letsAdjustThisOne.GetBooleanFieldFieldViewModel(nameof(PluginTrigger.PreImageAllFields)).Value = true; //save Assert.IsTrue(entryViewModel.Validate()); entryViewModel.OnSave(); //verify image created image = XrmRecordService.GetFirst(Entities.sdkmessageprocessingstepimage, Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid, updatedTrigger.Id); Assert.IsNotNull(image); Assert.IsNull(image.GetStringField(Fields.sdkmessageprocessingstepimage_.attributes)); var solutionComponents = XrmRecordService.GetSolutionComponents(packageSettings.Solution.Id, OptionSets.SolutionComponent.ObjectTypeCode.SDKMessageProcessingStep); Assert.IsTrue(triggers.All(t => solutionComponents.Contains(t.Id))); }
private void LoadAssemblyDetails() { LoadingViewModel.LoadingMessage = "Loading Assembly"; Request.AssemblyName = VisualStudioService.GetSelectedProjectAssemblyName(); if (string.IsNullOrWhiteSpace(Request.AssemblyName)) { throw new NullReferenceException("Could Not Find Assembly Name"); } var assemblyRecord = XrmRecordService.GetFirst(Entities.pluginassembly, Fields.pluginassembly_.name, Request.AssemblyName); if (assemblyRecord == null) { throw new NullReferenceException("There is no plugin assembly deployed in the dynamics instance with a matching name. Try the deploy assembly option to deploy a new plugin assembly, or rename the assembly to match an existing assembly deployed to the instance"); } LoadingViewModel.LoadingMessage = "Loading Plugin Types"; var pluginTypes = XrmRecordService.RetrieveAllAndClauses(Entities.plugintype, new[] { new Condition(Fields.plugintype_.pluginassemblyid, ConditionType.Equal, assemblyRecord.Id) }); if (!pluginTypes.Any()) { throw new NullReferenceException("There No Plugin Types Deployed In This Assembly So No Triggers Can Be Created For Them"); } LoadingViewModel.LoadingMessage = "Loading Plugin Triggers"; Request.SetSdkMessageStepsPre(XrmRecordService.RetrieveAllOrClauses(Entities.sdkmessageprocessingstep, pluginTypes.Select( pt => new Condition(Fields.sdkmessageprocessingstep_.plugintypeid, ConditionType.Equal, pt.Id)))); var sdkMessageStepsWithFilter = Request.GetSdkMessageStepsPre() .Where(sms => sms.GetField(Fields.sdkmessageprocessingstep_.sdkmessagefilterid) != null); LoadingViewModel.LoadingMessage = "Loading Plugin Filters"; var filters = !sdkMessageStepsWithFilter.Any() ? new IRecord[0] : XrmRecordService.RetrieveAllOrClauses(Entities.sdkmessagefilter, sdkMessageStepsWithFilter.Select( sms => new Condition(Fields.sdkmessagefilter_.sdkmessagefilterid, ConditionType.Equal, sms.GetLookupId(Fields.sdkmessageprocessingstep_.sdkmessagefilterid)))); LoadingViewModel.LoadingMessage = "Loading Plugin Images"; var preImages = Request.GetSdkMessageStepsPre().Any() ? XrmRecordService.RetrieveAllOrClauses(Entities.sdkmessageprocessingstepimage, Request.GetSdkMessageStepsPre().Select(m => new Condition(Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid, ConditionType.Equal, m.Id))) .Where(i => i.GetOptionKey(Fields.sdkmessageprocessingstepimage_.imagetype) == OptionSets.SdkMessageProcessingStepImage.ImageType.PreImage.ToString()) .GroupBy(i => i.GetLookupField(Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid)) .Where(g => g.Key != null && g.Key.Id != null) .ToDictionary(i => i.Key.Id, g => g.First()) : new Dictionary <string, IRecord>(); var triggers = new List <PluginTrigger>(); foreach (var item in Request.GetSdkMessageStepsPre()) { var filterId = item.GetLookupId(Fields.sdkmessageprocessingstep_.sdkmessagefilterid); var matchingFilters = filters.Where(f => f.Id == filterId); var filter = matchingFilters.Any() ? matchingFilters.First() : null; var recordType = filter == null ? null : filter.GetStringField(Fields.sdkmessagefilter_.primaryobjecttypecode); RecordType recordTypeObj = null; if (recordType != null && recordType != "none") { try { recordTypeObj = new RecordType(recordType, XrmRecordService.GetDisplayName(recordType)); } catch (Exception) { } } var rank = item.GetIntegerField(Fields.sdkmessageprocessingstep_.rank); var name = item.GetStringField(Fields.sdkmessageprocessingstep_.name); var stage = item.GetOptionKey(Fields.sdkmessageprocessingstep_.stage); var mode = item.GetOptionKey(Fields.sdkmessageprocessingstep_.mode); var filteringAttributesString = item.GetStringField(Fields.sdkmessageprocessingstep_.filteringattributes); var trigger = new PluginTrigger(); //load trigger details trigger.Id = item.Id; //for some unknown reason this field was setting the target type ot sdkmessage filter //despite the target being plugin type so I had to implement this to correct the type //the name is popuated after the loop trigger.Message = item.GetField(Fields.sdkmessageprocessingstep_.sdkmessageid) as Lookup;// filter == null ? null : filter.GetLookupField(Fields.sdkmessagefilter_.sdkmessageid); item.SetField(Fields.sdkmessageprocessingstep_.plugintypeid, new Lookup(Entities.plugintype, item.GetLookupId(Fields.sdkmessageprocessingstep_.plugintypeid), null), XrmRecordService); trigger.Plugin = item.GetLookupField(Fields.sdkmessageprocessingstep_.plugintypeid); trigger.RecordType = recordTypeObj; trigger.Stage = stage.ParseEnum <PluginTrigger.PluginStage>(); trigger.Mode = mode.ParseEnum <PluginTrigger.PluginMode>(); trigger.Rank = rank; trigger.FilteringFields = filteringAttributesString == null ? new RecordField[0] : filteringAttributesString.Split(',') .Select(s => s.Trim()) .Where(s => !string.IsNullOrWhiteSpace(s)) .Select(s => new RecordField(s, XrmRecordService.GetFieldLabel(s, recordType))) .ToArray(); trigger.SpecificUserContext = item.GetLookupField(Fields.sdkmessageprocessingstep_.impersonatinguserid); //load image details if there is one if (trigger.Id != null) { if (!preImages.ContainsKey(item.Id)) { trigger.PreImageAllFields = false; } else { var preImage = preImages[item.Id]; var attributes = preImage.GetStringField(Fields.sdkmessageprocessingstepimage_.attributes); trigger.PreImageAllFields = string.IsNullOrWhiteSpace(attributes); trigger.PreImageFields = attributes == null ? new RecordField[0] : attributes .Split(',') .Select(s => s.Trim()) .Where(s => !string.IsNullOrWhiteSpace(s)) .Select(s => new RecordField(s, XrmRecordService.GetFieldLabel(s, recordType))) .ToArray(); trigger.PreImageName = preImage.GetStringField(Fields.sdkmessageprocessingstepimage_.entityalias); trigger.PreImageId = preImage.Id; trigger.PreImageIdUnique = preImage.GetField(Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepimageidunique)?.ToString(); } } triggers.Add(trigger); } LoadingViewModel.LoadingMessage = "Loading Plugin Names"; //since I had to correct the target type for this fields lookup need to populate the name if (triggers.Any()) { XrmRecordService.PopulateLookups(new Dictionary <string, List <Lookup> >() { { Fields.sdkmessageprocessingstep_.plugintypeid, triggers.Select(t => t.Plugin).ToList() } }, null); } triggers = triggers .OrderBy(t => t.RecordType?.Value) .ThenBy(t => t.Message?.Name) .ThenByDescending(t => t.Stage) .ThenByDescending(t => t.Mode).ToList(); Request.Triggers = triggers; Request.Assembly = assemblyRecord.ToLookup(); LoadingViewModel.LoadingMessage = "Loading Plugins Into Grid"; }
public void DeploymentCreateAndDeployPackageModuleTest() { DeleteAll(Entities.account); DeleteAll(Entities.contact); var account = CreateAccount(); var solution = XrmRecordService.GetFirst("solution", XrmRecordService.GetPrimaryField("solution"), "Test Components"); Assert.IsNotNull(solution); FileUtility.DeleteFiles(TestingFolder); var createDeploymentPackageRequest = new CreatePackageRequest(); createDeploymentPackageRequest.FolderPath = new Folder(TestingFolder); createDeploymentPackageRequest.Solution = solution.ToLookup(); createDeploymentPackageRequest.ThisReleaseVersion = "3.0.0.0"; createDeploymentPackageRequest.SetVersionPostRelease = "4.0.0.0"; createDeploymentPackageRequest.DataToInclude = new[] { new ExportRecordType() { RecordType = new RecordType(Entities.account, Entities.account), Type = ExportType.AllRecords, }, new ExportRecordType() { RecordType = new RecordType(Entities.contact, Entities.contact), Type = ExportType.AllRecords } }; var createApplication = CreateAndLoadTestApplication <CreatePackageModule>(); var response = createApplication.NavigateAndProcessDialog <CreatePackageModule, CreatePackageDialog, ServiceResponseBase <DataImportResponseItem> >(createDeploymentPackageRequest); Assert.IsFalse(response.HasError); Assert.IsTrue(FileUtility.GetFiles(TestingFolder).First().EndsWith(".zip")); Assert.IsTrue(FileUtility.GetFolders(TestingFolder).First().EndsWith("Data")); Assert.IsTrue(FileUtility.GetFiles((FileUtility.GetFolders(TestingFolder).First())).Any()); solution = XrmRecordService.Get(solution.Type, solution.Id); Assert.AreEqual("4.0.0.0", solution.GetStringField(Fields.solution_.version)); //delete for recreation XrmService.Delete(account); //Okay now lets deploy it var deployRequest = new DeployPackageRequest(); deployRequest.FolderContainingPackage = new Folder(TestingFolder); deployRequest.Connection = GetSavedXrmRecordConfiguration(); var deployApplication = CreateAndLoadTestApplication <DeployPackageModule>(); response = deployApplication.NavigateAndProcessDialog <DeployPackageModule, DeployPackageDialog, ServiceResponseBase <DataImportResponseItem> >(deployRequest); Assert.IsFalse(response.HasError); solution = XrmRecordService.Get(solution.Type, solution.Id); Assert.AreEqual("3.0.0.0", solution.GetStringField(Fields.solution_.version)); //should be recreated account = Refresh(account); createDeploymentPackageRequest = new CreatePackageRequest(); createDeploymentPackageRequest.FolderPath = new Folder(TestingFolder); createDeploymentPackageRequest.Solution = solution.ToLookup(); createDeploymentPackageRequest.ThisReleaseVersion = "3.0.0.0"; createDeploymentPackageRequest.SetVersionPostRelease = "4.0.0.0"; createDeploymentPackageRequest.DeployPackageInto = GetSavedXrmRecordConfiguration(); createDeploymentPackageRequest.DataToInclude = new[] { new ExportRecordType() { RecordType = new RecordType(Entities.account, Entities.account), Type = ExportType.AllRecords }, new ExportRecordType() { RecordType = new RecordType(Entities.contact, Entities.contact), Type = ExportType.AllRecords } }; //error if already .zips on the folder FileUtility.WriteToFile(TestingFolder, "Fake.zip", "FakeContent"); createApplication = CreateAndLoadTestApplication <CreatePackageModule>(); try { createApplication.NavigateAndProcessDialog <CreatePackageModule, CreatePackageDialog, ServiceResponseBase <DataImportResponseItem> >(createDeploymentPackageRequest); Assert.Fail(); } catch (Exception ex) { Assert.IsFalse(ex is AssertFailedException); } FileUtility.DeleteFiles(TestingFolder); FileUtility.DeleteSubFolders(TestingFolder); response = createApplication.NavigateAndProcessDialog <CreatePackageModule, CreatePackageDialog, ServiceResponseBase <DataImportResponseItem> >(createDeploymentPackageRequest); Assert.IsFalse(response.HasError); solution = XrmRecordService.Get(solution.Type, solution.Id); Assert.AreEqual("3.0.0.0", solution.GetStringField(Fields.solution_.version)); }
private string LoadAssemblyDetails() { AssemblyFile = VisualStudioService.BuildSelectedProjectAndGetAssemblyName(); if (string.IsNullOrWhiteSpace(AssemblyFile)) { return("Could Not Find Built Assembly. Check The Build Result For Errors"); } var fileInfo = new FileInfo(AssemblyFile); var assemblyName = fileInfo.Name.Substring(0, fileInfo.Name.LastIndexOf(fileInfo.Extension, StringComparison.Ordinal)); var bytes = File.ReadAllBytes(AssemblyFile); var assemblyContent = Convert.ToBase64String(bytes); //okay this crazy stuff is to load the assembly dll in a different app domain //that way it may be loaded, inspected, then released (removing any lock on the assembly file) //when the appdomain is unloaded //the loading and inspection is done in an object PluginAssemblyReader //which is loaded in the context of the separate app domain var myDomain = AppDomain.CreateDomain("JosephM.XRM.VSIX.DeployAssemblyCommand", null, null); AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; IEnumerable <PluginAssemblyReader.PluginType> plugins; bool isSigned = false; try { var reader = (PluginAssemblyReader) myDomain.CreateInstanceFrom( Assembly.GetExecutingAssembly().Location, typeof(PluginAssemblyReader).FullName).Unwrap(); var loadResponse = reader.LoadTypes(AssemblyFile); isSigned = loadResponse.IsSigned; var loadedPlugins = loadResponse.PluginTypes; plugins = loadedPlugins.Select(p => new PluginAssemblyReader.PluginType(p.Type, p.TypeName)).ToArray(); } finally { AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve; if (null != myDomain) { AppDomain.Unload(myDomain); } } if (!isSigned) { return("Assembly Cannot By Deployed. You Need To Sign The Assembly With A Strong Named Key File"); } if (!plugins.Any()) { return("Assembly Cannot By Deployed. No Plugin Classes Were Found In The Assembly"); } Request.AssemblyName = assemblyName; Request.Content = assemblyContent; var preAssembly = XrmRecordService.GetFirst(Entities.pluginassembly, Fields.pluginassembly_.name, assemblyName); if (preAssembly != null) { Request.Id = preAssembly.Id; Request.IsolationMode = preAssembly.GetOptionKey(Fields.pluginassembly_.isolationmode).ParseEnum <DeployAssemblyRequest.IsolationMode_>(); } var pluginTypes = new List <PluginType>(); Request.PluginTypes = pluginTypes; foreach (var item in plugins) { var pluginType = new PluginType(); pluginType.TypeName = item.TypeName; //get the type name after "." as the name var startIndex = item.TypeName.LastIndexOf(".", StringComparison.Ordinal); if (startIndex != -1 && item.TypeName.Length > startIndex + 1) { startIndex = startIndex + 1; } else { startIndex = 0; } pluginType.FriendlyName = item.TypeName.Substring(startIndex); pluginType.Name = item.TypeName.Substring(startIndex); pluginType.IsWorkflowActivity = item.Type == PluginAssemblyReader.PluginType.XrmPluginType.WorkflowActivity; pluginType.InAssembly = true; pluginTypes.Add(pluginType); } Request.SetPreTypeRecords(preAssembly == null ? new IRecord[0] : XrmRecordService.RetrieveAllAndClauses(Entities.plugintype, new[] { new Condition(Fields.plugintype_.pluginassemblyid, ConditionType.Equal, Request.Id) })); foreach (var item in Request.GetPreTypeRecords()) { var matchingItems = pluginTypes.Where(pt => item.GetStringField(Fields.plugintype_.typename) == pt.TypeName); var matchingItem = matchingItems.Any() ? matchingItems.First() : null; if (matchingItem == null) { //if the plugin was not loaded by the types in the assembly //then create a new one matchingItem = new PluginType(); pluginTypes.Add(matchingItem); matchingItem.TypeName = item.GetStringField(Fields.plugintype_.typename); matchingItem.IsWorkflowActivity = item.GetBoolField(Fields.plugintype_.isworkflowactivity); } matchingItem.Id = item.Id; matchingItem.FriendlyName = item.GetStringField(Fields.plugintype_.friendlyname); matchingItem.Name = item.GetStringField(Fields.plugintype_.name); matchingItem.GroupName = item.GetStringField(Fields.plugintype_.workflowactivitygroupname); } foreach (var item in pluginTypes) { var matchingItems = Request.GetPreTypeRecords().Where(pt => pt.GetStringField(Fields.plugintype_.typename) == item.TypeName); if (matchingItems.Any()) { var matchingItem = matchingItems.First(); item.IsDeployed = true; item.Id = matchingItem.Id; item.Name = matchingItem.GetStringField(Fields.plugintype_.friendlyname); item.GroupName = matchingItem.GetStringField(Fields.plugintype_.workflowactivitygroupname); } } return(null); }
public override void ExecuteExtention(DeployIntoFieldRequest request, DeployIntoFieldResponse response, LogController controller) { var records = new List <IRecord>(); var publishIds = new List <string>(); var numberToDo = request.Files.Count(); var numberDone = 0; foreach (var file in request.Files) { var fileInfo = new FileInfo(file); controller.UpdateProgress(++numberDone, numberToDo, "Importing " + fileInfo.Name); var thisResponseItem = new DeployIntoFieldResponseItem() { Name = fileInfo.Name }; response.AddResponseItem(thisResponseItem); try { var containingFolderName = fileInfo.Directory.Name; //get target record type string recordType = null; if (Service.GetAllRecordTypes().Any(r => r == containingFolderName)) { recordType = Service.GetAllRecordTypes().First(r => r == containingFolderName); } else if (Service.GetAllRecordTypes().Any(r => Service.GetDisplayName(r)?.ToLower() == containingFolderName.ToLower())) { recordType = Service.GetAllRecordTypes().First(r => Service.GetDisplayName(r)?.ToLower() == containingFolderName.ToLower()); } else { throw new NullReferenceException($"Could not find matching type by logical or display name for folder name of {containingFolderName}"); } if (recordType == Entities.adx_webfile) { //this one goes into an attachment var matchingRecord = Service.GetFirst(recordType, Service.GetPrimaryField(recordType), fileInfo.Name); if (matchingRecord == null) { throw new NullReferenceException($"There is no {Service.GetDisplayName(recordType)} record name {fileInfo.Name} to load the file attachment into"); } //get matching attachment by name else create a new one var fileAttachments = Service.RetrieveAllAndClauses(Entities.annotation, new[] { new Condition(Fields.annotation_.filename, ConditionType.Equal, fileInfo.Name), new Condition(Fields.annotation_.objectid, ConditionType.Equal, matchingRecord.Id) }).OrderBy(n => n.GetDateTime(Fields.annotation_.createdon)).ToArray(); var contentBytes = File.ReadAllBytes(file); var contentBase64String = Convert.ToBase64String(contentBytes); if (fileAttachments.Any()) { //lets update the last modifed one var attachmentToUpdate = fileAttachments.First(); if (attachmentToUpdate.GetStringField(Fields.annotation_.documentbody) != contentBase64String) { attachmentToUpdate.SetField(Fields.annotation_.documentbody, contentBase64String, Service); Service.Update(attachmentToUpdate, new[] { Fields.annotation_.documentbody }); thisResponseItem.Updated = true; } } else { //lets create a new attachment var newAttachment = Service.NewRecord(Entities.annotation); newAttachment.SetLookup(Fields.annotation_.objectid, matchingRecord.Id, matchingRecord.Type); newAttachment.SetField(Fields.annotation_.subject, fileInfo.Name, Service); newAttachment.SetField(Fields.annotation_.filename, fileInfo.Name, Service); newAttachment.SetField(Fields.annotation_.documentbody, contentBase64String, Service); Service.Create(newAttachment); thisResponseItem.Created = true; } } else { //get the record with the same name as the file var fileNameSansExtention = fileInfo.Name.Substring(0, fileInfo.Name.LastIndexOf(".")); var conditions = new List <Condition> { new Condition(Service.GetPrimaryField(recordType), ConditionType.Equal, fileNameSansExtention) }; if (recordType == Entities.adx_webpage) { conditions.Add(new Condition(Fields.adx_webpage_.adx_rootwebpageid, ConditionType.NotNull)); } var matchingRecords = Service.RetrieveAllAndClauses(recordType, conditions); if (matchingRecords.Count() != 1) { throw new NullReferenceException($"Could not find {Service.GetDisplayName(recordType)} named {fileInfo.Name} to update"); } var matchingRecord = matchingRecords.First(); var targetField = GetTargetField(fileInfo, recordType); var contentText = File.ReadAllText(file); if (matchingRecord.GetStringField(targetField) != contentText) { matchingRecord.SetField(targetField, contentText, Service); Service.Update(matchingRecord, new[] { targetField }); thisResponseItem.Updated = true; } } } catch (Exception ex) { thisResponseItem.Exception = ex; } } }
public void XrmRecordDebug() { var config = XrmConfiguration; var views = XrmRecordService.GetFirst("sdkmessagefilter", "primaryobjecttypecode", "none"); }