Esempio n. 1
0
        /// <summary>
        /// Code factory framework calls this method when the command has been executed.
        /// </summary>
        /// <param name="result">The code factory model that has generated and provided to the command to process.</param>
        public override async Task ExecuteCommandAsync(VsDocument result)
        {
            try
            {
                //User Control
                var migrateDialog = await VisualStudioActions.UserInterfaceActions.CreateVsUserControlAsync <MigrateWebFormDialog>();

                //Get Project List
                var solution = await VisualStudioActions.SolutionActions.GetSolutionAsync();

                //Set properties on the dialog
                var projects = await solution.GetProjectsAsync(false);

                migrateDialog.SolutionProjects = projects;
                migrateDialog.FormToMigrate    = result;

                //Show the dialog
                await VisualStudioActions.UserInterfaceActions.ShowDialogWindowAsync(migrateDialog);
            }
            catch (Exception unhandledError)
            {
                _logger.Error($"The following unhandled error occured while executing the solution explorer project document command {commandTitle}. ",
                              unhandledError);
            }
        }
        /// <summary>
        /// Extension method that copies a <see cref="VsDocument"/> from a source project to a target location in a supplied destination directory.
        /// Will replace the source project directory path with a new root destination path.
        /// This will overwrite the existing file.
        /// </summary>
        /// <param name="source">The document to be copied</param>
        /// <param name="sourceProjectDirectory">The source project directory to be replaced.</param>
        /// <param name="rootDestinationDirectory">The new target destination path for the file.</param>
        /// <returns>Null if the file was not copied, or the fully qualified path where the file was copied to.</returns>
        public static string CopyProjectFile(this VsDocument source, string sourceProjectDirectory,
                                             string rootDestinationDirectory)
        {
            //Bounds checking to make sure all data has been passed in correctly. If not return null.
            if (source == null)
            {
                return(null);
            }
            if (string.IsNullOrEmpty(sourceProjectDirectory))
            {
                return(null);
            }
            if (string.IsNullOrEmpty(rootDestinationDirectory))
            {
                return(null);
            }

            //Setting the result variable.
            string result = null;

            try
            {
                //Loading the source file path from the visual studio document.
                var sourceFile = source.Path;

                //Replacing the source path with the target destination directory.
                var destinationFile = sourceFile.Replace(sourceProjectDirectory, rootDestinationDirectory);

                //Making sure the directory already exists in the target project, if it does not go ahead and add it to the project.
                var destinationDirectory = Path.GetDirectoryName(destinationFile);

                if (string.IsNullOrEmpty(destinationDirectory))
                {
                    return(null);
                }

                if (!Directory.Exists(destinationDirectory))
                {
                    Directory.CreateDirectory(destinationDirectory);
                }

                //Copying the project file to the new project.
                File.Copy(sourceFile, destinationFile, true);

                //Returning the new file location of the project file in the new project.
                result = destinationFile;
            }
            // ReSharper disable once EmptyGeneralCatchClause
            catch (Exception)
            {
                //An error occurred we are going to swallow the exception and return a null return type.
                return(null);
            }

            return(result);
        }
        /// <summary>
        /// Adds a new C# document to the parent project or folder of the current c# document.
        /// </summary>
        /// <param name="source">C# source document.</param>
        /// <param name="sourceCode">The source code to be added to the new code file.</param>
        /// <param name="targetFileName">The target file name of the new document.</param>
        /// <returns></returns>
        public static async Task <CsSource> AddCSharpCodeFileToParentAsync(this VsCSharpSource source, string sourceCode,
                                                                           string targetFileName)
        {
            if (source == null)
            {
                throw new CodeFactoryException("No visual studio c# source was provided cannot add C# code file.");
            }
            if (string.IsNullOrEmpty(targetFileName))
            {
                throw new CodeFactoryException("No filename was provided cannot add the C# code file.");
            }

            var parent = await source.GetCSharpSourceDocumentParentAsync();

            if (parent.ParentModel == null)
            {
                throw new CodeFactoryException("No project or project folder was found, cannot add the C# code file.");
            }


            VsDocument document = null;

            if (parent.IsProject)
            {
                var project = parent.ParentModel as VsProject;

                if (project == null)
                {
                    throw new CodeFactoryException("Could load the project information, cannot add the C# code file.");
                }

                document = await project.AddDocumentAsync(targetFileName, sourceCode);
            }
            else
            {
                var projectFolder = parent.ParentModel as VsProjectFolder;

                if (projectFolder == null)
                {
                    throw new CodeFactoryException("Could load the project folder information, cannot add the C# code file.");
                }

                document = await projectFolder.AddDocumentAsync(targetFileName, sourceCode);
            }

            var csDocument = await document.GetCSharpSourceModelAsync();

            return(csDocument);
        }
Esempio n. 4
0
        /// <summary>
        /// Validation logic that will determine if this command should be enabled for execution.
        /// </summary>
        /// <param name="result">The target model data that will be used to determine if this command should be enabled.</param>
        /// <returns>Boolean flag that will tell code factory to enable this command or disable it.</returns>
        public override async Task <bool> EnableCommandAsync(VsDocument result)
        {
            //Result that determines if the the command is enabled and visible in the context menu for execution.
            bool isEnabled = false;

            try
            {
                isEnabled = result.Name.Contains("aspx");
            }
            catch (Exception unhandledError)
            {
                _logger.Error($"The following unhandled error occured while checking if the solution explorer project document command {commandTitle} is enabled. ",
                              unhandledError);
                isEnabled = false;
            }

            return(isEnabled);
        }
Esempio n. 5
0
        private async Task <CsSource> UpdateSubscriptionAsync(CsField subscriptionField, CsClass sourceClass, VsCSharpSource source)
        {
            SourceFormatter formatter        = new SourceFormatter();
            string          injectSourceCode = null;

            var contract = subscriptionField.DataType.GetInterfaceModel();

            if (contract == null)
            {
                return(null);
            }

            CsSource sourceCode = source.SourceCode;

            try
            {
                CsClass currentClass = sourceClass;

                var events = contract.Events;

                var subscribePath = ContractHelper.GetSubscribeFilePath(currentClass);


                if (!subscribePath.hasFile)
                {
                    var manager = sourceCode.LoadNamespaceManager(sourceClass.Namespace);

                    var parent = await source.GetParentAsync();

                    if (parent == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }

                    VsDocument generatedDocument  = null;
                    string     partialClassSource = CSharpSourceGenerationCommon.GeneratePartialClass(currentClass, manager);
                    if (parent.ModelType == VisualStudioModelType.ProjectFolder)
                    {
                        var parentFolder = parent as VsProjectFolder;

                        if (parentFolder == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        generatedDocument = await parentFolder.AddDocumentAsync(Path.GetFileName(subscribePath.filePath),
                                                                                partialClassSource);
                    }
                    else
                    {
                        var parentProject = parent as VsProject;

                        if (parentProject == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        generatedDocument = await parentProject.AddDocumentAsync(subscribePath.filePath,
                                                                                 partialClassSource);
                    }
                    sourceCode = await generatedDocument.GetCSharpSourceModelAsync();

                    sourceCode = await sourceCode.AddMissingNamespaces(contract.Events, currentClass.Namespace);

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;

                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }
                else
                {
                    var parent = await source.GetParentAsync();

                    VsCSharpSource sourceDocument = null;
                    if (parent.ModelType == VisualStudioModelType.ProjectFolder)
                    {
                        var parentFolder = parent as VsProjectFolder;

                        if (parentFolder == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        var children = await parentFolder.GetChildrenAsync(false, true);

                        sourceDocument = children.Where(c => c.ModelType == VisualStudioModelType.CSharpSource)
                                         .Cast <VsCSharpSource>()
                                         .FirstOrDefault(s => s.SourceCode.SourceDocument == subscribePath.filePath);
                    }
                    else
                    {
                        var parentProject = parent as VsProject;

                        if (parentProject == null)
                        {
                            throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                        }

                        var children = await parentProject.GetChildrenAsync(false, true);

                        sourceDocument = children.Where(c => c.ModelType == VisualStudioModelType.CSharpSource)
                                         .Cast <VsCSharpSource>()
                                         .FirstOrDefault(s => s.SourceCode.SourceDocument == subscribePath.filePath);;
                    }

                    if (sourceDocument == null)
                    {
                        throw new CodeFactoryException("Could load the contract document.");
                    }

                    sourceCode = sourceDocument.SourceCode;

                    sourceCode = await sourceCode.AddMissingNamespaces(contract.Events, currentClass.Namespace);

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var namespaceManager = sourceCode.LoadNamespaceManager(currentClass.Namespace);

                foreach (var contractEvent in contract.Events)
                {
                    var eventHandlerName =
                        CSharpSourceGenerationWPF.GenerateContractEventHandlerMethodName(subscriptionField, contractEvent);

                    if (eventHandlerName == null)
                    {
                        throw new CodeFactoryException($"Could not create the source code for a contract event handler.");
                    }

                    if (currentClass.Methods.Any(m => m.Name == eventHandlerName))
                    {
                        continue;
                    }

                    var eventHandlerSource = CSharpSourceGenerationWPF.GenerateContractEventHandlerMethod(subscriptionField, contractEvent,
                                                                                                          namespaceManager);

                    if (eventHandlerSource == null)
                    {
                        throw new CodeFactoryException($"Could not create the source code for the event handler {eventHandlerName}");
                    }

                    sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, eventHandlerSource));

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var subscriptionName   = CSharpSourceGenerationWPF.GenerateContractSubscriptionMethodName(subscriptionField);
                var subscriptionMethod = currentClass.Methods.FirstOrDefault(m => m.Name == subscriptionName);

                if (subscriptionMethod != null)
                {
                    sourceCode = await subscriptionMethod.DeleteAsync();

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var subscriptionSource = CSharpSourceGenerationWPF.GenerateContractSubscriptionMethod(subscriptionField, contract);

                if (subscriptionSource == null)
                {
                    throw new CodeFactoryException("Cannot generate the subscription contract source code.");
                }

                sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, subscriptionSource));

                currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                if (currentClass == null)
                {
                    throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                }

                var releaseName   = CSharpSourceGenerationWPF.GenerateContractReleaseMethodName(subscriptionField);
                var releaseMethod = currentClass.Methods.FirstOrDefault(m => m.Name == releaseName);

                if (releaseMethod != null)
                {
                    sourceCode = await releaseMethod.DeleteAsync();

                    currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass;
                    if (currentClass == null)
                    {
                        throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription");
                    }
                }

                var releaseSource = CSharpSourceGenerationWPF.GenerateContractReleaseMethod(subscriptionField, contract);

                if (releaseSource == null)
                {
                    throw new CodeFactoryException("Cannot generate the release contract source code.");
                }

                sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, releaseSource));
            }
            catch (CodeFactoryException)
            {
                throw;
            }
            catch (Exception unhandledException)
            {
                throw new CodeFactoryException("The following unhandledException occured", unhandledException);
            }

            return(sourceCode);
        }
        /// <summary>
        /// Gets the immediate VsProject Folder objects that this Document object lives in.
        /// This list is in reverse order from leaf-to-trunk. An empty list is returned if the document lives in the root of the project.
        /// </summary>
        /// <param name="sourceDocument">The visual studio document to search for.</param>
        /// <returns>List of the the parent <see cref="VsProjectFolder"/> found.</returns>
        public static async Task <List <VsProjectFolder> > GetParentFolders(this VsDocument sourceDocument)
        {
            //Stores the list of parents being returned.
            List <VsProjectFolder> folderHierarchy = new List <VsProjectFolder>();

            //Getting the parent of the source document.
            var parentModel = await sourceDocument.GetParentAsync();

            //If no parent was found return the empty list.
            if (parentModel == null)
            {
                return(folderHierarchy);
            }

            //Climb back up the file and folders until you get to the hosting project.
            while (!parentModel.ModelType.Equals(VisualStudioModelType.Project))
            {
                if (parentModel.ModelType.Equals(VisualStudioModelType.ProjectFolder))
                {
                    //Casting the model to the project folder.
                    var parentFolder = parentModel as VsProjectFolder;

                    //checking to make sure the cast ran clean.
                    if (parentFolder == null)
                    {
                        return(folderHierarchy);
                    }

                    //Adding the parent folder to the list to be returned
                    folderHierarchy.Add(parentFolder);

                    //Getting the next parent and confirming it was found.
                    parentModel = await(parentFolder).GetParentAsync();
                    if (parentModel == null)
                    {
                        return(folderHierarchy);
                    }
                }
                else
                {
                    //Casting to the parent document model.
                    var parentDocument = parentModel as VsDocument;

                    //If the cast failed return what was found.
                    if (parentDocument == null)
                    {
                        return(folderHierarchy);
                    }

                    //Getting the next parent and confirming it was found.
                    parentModel = await(parentDocument).GetParentAsync();
                    if (parentModel == null)
                    {
                        return(folderHierarchy);
                    }
                }
            }

            //Returning the found parent models.
            return(folderHierarchy);
        }
        /// <summary>
        /// Migrates the site.master layout files from the source WebForms project into the \Shared folder
        /// in the Blazor target application project.
        /// </summary>
        /// <param name="webFormSiteMasterFiles">The flattened list of WebForms project objects/files</param>
        /// <param name="blazorServerProject">The target Blazor project object</param>
        /// <returns></returns>
        ///         private async Task ConvertAspxPage(VsDocument sourcePage, VsProject targetProject, VsProjectFolder targetPagesFolder, VsCSharpSource sourceCodeBehind = null)
        private async Task <string> ConvertLayoutFiles(IEnumerable <VsModel> webFormSiteMasterFiles, VsProject blazorServerProject)
        {
            string headerData = null;
            //put the files in the target project
            var targetFolder = await blazorServerProject.CheckAddFolder("Shared");

            try
            {
                foreach (var layoutFile in webFormSiteMasterFiles)
                {
                    //We don't want to touch/migrate any of the *.designer files
                    if (layoutFile.Name.ToLower().Contains("designer"))
                    {
                        continue;
                    }

                    String targetFileName = layoutFile.Name.Replace(".", "");
                    //Get any existing children in the targetFolder that match.
                    var existingBlazorMatches = await targetFolder.GetChildrenAsync(true, false);

                    var docMatches = existingBlazorMatches.Where(p => p.Name.ToLower().Contains(targetFileName.ToLower())).Cast <VsDocument>();

                    foreach (VsDocument matchFile in docMatches)
                    {
                        //delete each matched file in the target folder.
                        await matchFile.DeleteAsync();
                    }

                    //work on just the Site.Master file which is basically a specialized *.aspx file.
                    if (!layoutFile.Name.ToLower().Contains(".cs"))
                    {
                        var docObj         = layoutFile as VsDocument;
                        var textFromResult = await docObj.GetDocumentContentAsStringAsync();

                        //grab the <%Page element from the source and pull it from the text.  Its meta data anyway and just screws up the conversion down the line.
                        var pageHeaderData = System.Text.RegularExpressions.Regex.Match(textFromResult, @"<%@\s*[^%>]*(.*?)\s*%>").Value;

                        if (pageHeaderData.Length > 0)
                        {
                            textFromResult = Regex.Replace(textFromResult, @"<%@\s*[^%>]*(.*?)\s*%>", string.Empty);
                        }

                        //Swap ASP.NET string tokens for Razor syntax  (<%, <%@, <%:, <%#:, etc
                        var targetText = RemoveASPNETSyntax(textFromResult);

                        //Convert Site.Master file into razor syntax, specifically the asp:controls that might be used there.
                        var conversionData = await ReplaceAspControls(targetText);

                        //Drop the pageHeaderData into the Dictionary for later processing by any downstream T4 factories
                        conversionData.Add("HeaderData", pageHeaderData);

                        //Setup Page directives, using statements etc
                        var targetWithMeta = await SetRazorPageDirectives(targetFileName, conversionData);


                        VsDocument success = await _visualStudioActions.ProjectFolderActions.AddDocumentAsync(targetFolder, $"{targetFileName}.razor", targetWithMeta);

                        //Updating the dialog
                        await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages, MessageTypeEnum.Information,
                                                                       $"The file {targetFileName}.razor was copied to {targetFolder.Name}.");
                    }

                    //Get sibling/named code-behind file
                    //1. Get the children of this *.aspx file
                    //2. Grab the doc that has the same name with a ".cs" extension on the end of it
                    if (layoutFile.Name.Contains(".cs"))
                    {
                        targetFileName = layoutFile.Name.Replace(".cs", "");
                        targetFileName = targetFileName.Replace(".", "");

                        var sourceObj          = layoutFile as VsCSharpSource;
                        var codeSource         = sourceObj.SourceCode;
                        var metaDataDictionary = new Dictionary <string, string>();
                        metaDataDictionary.Add("Namespace", $"{blazorServerProject.Name}.Pages");

                        //Setup Page directives, using statements etc
                        //var targetWithMeta = await SetRazorPageDirectives(targetFileName, conversionData);
                        CsModelStore modelStore = new CsModelStore();
                        modelStore.SetModel(codeSource.Classes.FirstOrDefault());
                        var codebehind = await _visualStudioActions.ProjectFolderActions.AddDocumentAsync(targetFolder,
                                                                                                          $"{targetFileName}.razor.cs",
                                                                                                          Templates.PageCodeBehind.GenerateSource(modelStore, metaDataDictionary));

                        // Updating the dialog
                        await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages, MessageTypeEnum.Information,
                                                                       $"The file {targetFileName}.razor.cs was copied to {targetFolder.Name}.");
                    }
                }
            }

            catch (Exception unhandledError)
            {
                await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages, MessageTypeEnum.Error,
                                                               $"The following unhandled error occured while trying to migrate the layout files. '{unhandledError.Message}'");
            }
            return(headerData);
        }
        /// <summary>
        /// Helper method that converts Aspx Pages to Blazor pages.
        /// </summary>
        /// <param name="sourcePage">The source aspx page to be converted.</param>
        /// <param name="targetProject">The target blazor project to write to.</param>
        /// <param name="targetPagesFolder">The target visual studio project folder the converted aspx will be added to.</param>
        /// <param name="sourceCodeBehind">Optional parameter that provides the code behind file for the aspx page to be converted also.</param>
        /// <returns>Flag used to determine if the conversion was successful.</returns>
        private async Task ConvertAspxPage(VsDocument sourcePage, VsProject targetProject, VsProjectFolder targetPagesFolder, VsCSharpSource sourceCodeBehind = null, VsDocument sourceDocCodeBehind = null)
        {
            try
            {
                //Getting the content from the source document.
                var pageContent = await sourcePage.GetDocumentContentAsStringAsync(); //File.ReadAllText(result.Path);

                //grab the <%Page element from the source and pull it from the text.  Its meta data anyway and just screws up the conversion down the line.
                var pageHeaderData = System.Text.RegularExpressions.Regex.Match(pageContent, @"<%@\s*[^%>]*(.*?)\s*%>").Value;

                if (pageHeaderData.Length > 0)
                {
                    pageContent = Regex.Replace(pageContent, @"<%@\s*[^%>]*(.*?)\s*%>", string.Empty);
                }

                //Swap ASP.NET string tokens for Razor syntax  (<%, <%@, <%:, <%#:, etc
                var targetText = RemoveASPNETSyntax(pageContent);

                //Convert ASP.NET into Razor syntax.  **This actually presumes that any controls like <asp:ListView..
                //will have an equivalent Razor component in place called <ListView.. etc
                var conversionData = await ReplaceAspControls(targetText);

                //Drop the pageHeaderData into the Dictionary for later processing by any downstream T4 factories
                conversionData.Add("HeaderData", pageHeaderData);

                //Getting the source code from the code behind file provided.
                var codeSource = sourceCodeBehind?.SourceCode;
                if ((codeSource == null) && (sourceDocCodeBehind != null))
                {
                    codeSource = await sourceDocCodeBehind.GetCSharpSourceModelAsync();
                }

                //put the files in the target project
                String targetFileName = Path.GetFileNameWithoutExtension(sourcePage.Path);
                conversionData.Add("Namespace", $"{targetProject.DefaultNamespace}.Pages");

                //Setup Page directives, using statements etc
                var targetWithMeta = await SetRazorPageDirectives(targetFileName, conversionData);

                //Adding the converted content from the aspx page to the new razor page.
                VsDocument success = await targetPagesFolder.AddDocumentAsync($"{targetFileName}.razor", targetWithMeta);

                if (success != null)
                {
                    //Updating the dialog with the status the aspx page has been converted.
                    await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages,
                                                                   MessageTypeEnum.Information,
                                                                   $"Converted the aspx page to a razor page, added razor page {targetFileName}.razor");

                    //If we have the source code from the original aspx page add it to the razor pages folder.
                    if (codeSource != null)
                    {
                        //Creating a CodeFactory model store this will be used to pass data to a T4 factory.
                        CsModelStore modelStore = new CsModelStore();

                        //Adding the current class from the code behind into the model store for processing.
                        modelStore.SetModel(codeSource.Classes.FirstOrDefault());

                        //Processing the T4 factory and loading the source code.
                        var codeBehindFormattedSourceCode =
                            Templates.PageCodeBehind.GenerateSource(modelStore, conversionData);

                        //Calling the CodeFactory project system and adding a new code behind file and injecting the formatted code into the file.
                        var codeBehind = await targetPagesFolder.AddDocumentAsync($"{targetFileName}.razor.cs", codeBehindFormattedSourceCode);

                        if (codeBehind != null)
                        {
                            //Updating the dialog with the status the aspx page code behind has been converted.
                            await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages,
                                                                           MessageTypeEnum.Information,
                                                                           $"Converted the aspx page code behind file to a razor page code behind file, added code behind file {targetFileName}.razor.cs");
                        }
                        else
                        {
                            //Updating the dialog with the status the aspx page code behind failed
                            await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages,
                                                                           MessageTypeEnum.Error,
                                                                           $"Failed the conversion of the aspx page code behind file to a razor page code behind file {targetFileName}.razor.cs");
                        }
                    }
                }
                else
                {
                    //Updating the dialog with the status the aspx page failed conversion.
                    await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages,
                                                                   MessageTypeEnum.Error,
                                                                   $"Failed the conversion of the aspx page {targetFileName}.razor. Will not convert the code behind file.");
                }
            }
            catch (Exception unhandledError)
            {
                await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages, MessageTypeEnum.Error,
                                                               $"The following unhandled error occured while trying to convert the aspx page. '{unhandledError.Message}'");
            }
        }
        public async Task MigrateSingleASPXFile(VsDocument aspxSourcefile, VsProject blazorServerProject)
        {
            try
            {
                //VsCSharpSource aspxCodeBehindFile
                //Getting the formatted names that will be used in migrating the ASPX file and its code behind to the blazor project.
                string targetFileNameNoExtension   = Path.GetFileNameWithoutExtension(aspxSourcefile.Path);
                string aspxCodeBehindFileName      = $"{targetFileNameNoExtension}.aspx.cs";
                string razorPageFileName           = $"{targetFileNameNoExtension}.razor";
                string razorPageCodeBehindFileName = $"{targetFileNameNoExtension}.razor.cs";

                //Calling into the CodeFactory project system and getting all the direct children of the project.
                var blazorRootModels = await blazorServerProject.GetChildrenAsync(false);

                //Getting the pages folder from the blazor project.
                var blazorPagesFolder = blazorRootModels.FirstOrDefault(m =>
                                                                        m.ModelType == VisualStudioModelType.ProjectFolder & m.Name.ToLower().Equals("pages")) as VsProjectFolder;

                //If the pages folder was not found fail this step and return.
                if (blazorPagesFolder == null)
                {
                    await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages, MessageTypeEnum.Error,
                                                                   "No pages folder was found in the blazor project, cannot continue the aspx file conversion.");

                    return;
                }

                //Call the CodeFactory project system to get all the current children of the pages project folder.
                var pagesFolderModels = await blazorPagesFolder.GetChildrenAsync(true);

                //Filtering out everything but documents.
                var pages = pagesFolderModels.Where(m => m.ModelType == VisualStudioModelType.Document)
                            .Cast <VsDocument>();

                //Searching for an existing razor page. We will delete razor pages and recreate them.
                var currentRazorPage = pages.FirstOrDefault(p => p.Path.ToLower().EndsWith(razorPageFileName.ToLower()));

                if (currentRazorPage != null)
                {
                    //Razor page was found removing the razor page.
                    bool removedPage = await currentRazorPage.DeleteAsync();

                    if (removedPage)
                    {
                        await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages,
                                                                       MessageTypeEnum.Information, $"Removed the razor page {razorPageFileName}");

                        var currentRazorPageCodeBehind = pages.FirstOrDefault(p => p.Path.ToLower().EndsWith(razorPageCodeBehindFileName.ToLower()));

                        if (currentRazorPageCodeBehind != null)
                        {
                            if (File.Exists(currentRazorPageCodeBehind.Path))
                            {
                                bool removedCodeBehind = await currentRazorPageCodeBehind.DeleteAsync();

                                if (removedCodeBehind)
                                {
                                    await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages,
                                                                                   MessageTypeEnum.Information,
                                                                                   $"Removed the razor page code behind file {razorPageCodeBehindFileName}");
                                }
                                else
                                {
                                    await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages,
                                                                                   MessageTypeEnum.Error,
                                                                                   $"Could not remove the razor page code behind file {razorPageCodeBehindFileName}.The target ASPX file will not be migrated.");

                                    return;
                                }
                            }
                        }
                    }
                    else
                    {
                        await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages,
                                                                       MessageTypeEnum.Error,
                                                                       $"Could not remove the razor page {razorPageFileName}.The target ASPX file will not be migrated.");

                        return;
                    }
                }

                var aspxChildren = await aspxSourcefile.GetChildrenAsync(true);

                var codeBehindFile = aspxChildren
                                     .Where(c => (c.IsSourceCode == true) && (c.SourceType == SourceCodeType.CSharp)).FirstOrDefault();

                //Converting the aspx page and the code behind file if it was found.
                await ConvertAspxPage(aspxSourcefile, blazorServerProject, blazorPagesFolder, null, codeBehindFile);

                await _statusTracking.UpdateMigrationFinishedAsync();
            }
            catch (Exception unhandledError)
            {
                //Dumping the exception that occured directly into the status so the user can see what happened.
                await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.AspxPages, MessageTypeEnum.Error, $"The following unhandled error occured. '{unhandledError.Message}'");
            }
        }