Example #1
0
        /// <summary>
        /// Generates the source code from the T4 code factory.
        /// </summary>
        /// <param name="modelStore">The C# model storage that contains all the models to be used with the T4 factory.</param>
        /// <param name="modelData">Model data object used by the T4 factory.</param>
        /// <returns>The generated source code.</returns>
        public static string GenerateSource(CsModelStore modelStore, object modelData)
        {
            var factory = new MiddlewareConversion {
                CsModels = modelStore, ModelData = modelData
            };

            return(factory.TransformText());
        }
Example #2
0
        /// <summary>
        /// Generates the source code from the T4 code factory.
        /// </summary>
        /// <param name="modelStore">The C# model storage that contains all the models to be used with the T4 factory.</param>
        /// <param name="modelData">Model data object used by the T4 factory.</param>
        /// <returns>The generated source code.</returns>
        public static string GenerateSource(CsModelStore modelStore, object modelData)
        {
            var factory = new AddMemberMethod {
                CsModels = modelStore, ModelData = modelData
            };

            return(factory.TransformText());
        }
        /// <summary>
        /// Generates the source code from the T4 code factory.
        /// </summary>
        /// <param name="modelStore">The C# model storage that contains all the models to be used with the T4 factory.</param>
        /// <param name="modelData">Model data object used by the T4 factory.</param>
        /// <returns>The generated source code.</returns>
        public static string GenerateSource(CsModelStore modelStore, object modelData)
        {
            var factory = new PageCodeBehind {
                CsModels = modelStore, ModelData = modelData
            };

            return(factory.TransformText());
        }
Example #4
0
        /// <summary>
        /// Generates the source code from the T4 code factory.
        /// </summary>
        /// <param name="modelStore">The C# model storage that contains all the models to be used with the T4 factory.</param>
        /// <returns>The generated source code.</returns>
        public static string GenerateSource(CsModelStore modelStore)
        {
            var factory = new ModuleFactory {
                CsModels = modelStore, ModelData = null
            };

            return(factory.TransformText());
        }
        /// <summary>
        /// Generates the source code from the T4 code factory.
        /// </summary>
        /// <param name="modelStore">The C# model storage that contains all the models to be used with the T4 factory.</param>
        /// <param name="modelData">Model data object used by the T4 factory.</param>
        /// <returns>The generated source code.</returns>
        public static string GenerateSource(CsModelStore modelStore, object modelData)
        {
            var factory = new BundleConfigFactory {
                CsModels = modelStore, ModelData = modelData
            };

            return(factory.TransformText());
        }
        /// <summary>
        /// Migrates the definition of existing Http Modules that were used in the web forms project into the blazor project.
        /// </summary>
        /// <param name="webFormProjectData">Pre cached project data about the web forms project.</param>
        /// <param name="webFormProject">The web forms project that we are migrating data from.</param>
        /// <param name="blazorServerProject">The blazor server project this is being migrated to.</param>
        public async Task MigrateHttpModulesAsync(IReadOnlyList <VsModel> webFormProjectData, VsProject webFormProject, VsProject blazorServerProject)
        {
            try
            {
                //Letting the dialog know the http modules migration has started.
                await _statusTracking.UpdateStepStatusAsync(MigrationStepEnum.HttpModules, MigrationStatusEnum.Running);

                //find class(es) that inherit HttpApplication
                var handlerClasses = webFormProjectData.GetClassesThatImplementInterface("IHttpHandler");
                var moduleClasses  = webFormProjectData.GetClassesThatImplementInterface("IHttpModule");

                if (!handlerClasses.Any() && !moduleClasses.Any())
                {
                    //No handler classes or modules were found updating the status and exiting this step.
                    await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.Startup, MessageTypeEnum.Error,
                                                                   $"No classes were found in {webFormProject.Name} that inherit from either 'IHttpHandler' or 'IHttpModule'");

                    //Setting the status to passed wasn't a failure and the solution will not require these to be added.
                    await _statusTracking.UpdateStepStatusAsync(MigrationStepEnum.HttpModules, MigrationStatusEnum.Passed);

                    return;
                }

                //Making sure a modules folder exists, if it does not create it in the blazor server project.
                var modulesFolder = await blazorServerProject.CheckAddFolder("Modules");

                //Creating a dictionary that holds the target namespace for modules.
                var conversionData = new Dictionary <string, string>
                {
                    { "Namespace", $"{blazorServerProject.DefaultNamespace}.Modules" }
                };

                CsModelStore store = null;

                //Create a class file in the Modules folder from a T4 Template for each handler class
                foreach (CsSource source in handlerClasses)
                {
                    //Setting up the model data to pass off to a T4 Factory
                    store = new CsModelStore();
                    store.SetModel(source);

                    //Calling the T4 factory and getting back the formatted file content.
                    var fileContent = ModuleFactory.GenerateSource(store, conversionData);

                    //Calling CodeFactory project system API to add a new document to the project folder, also injecting the new file content into the file.
                    await modulesFolder.AddDocumentAsync($"{Path.GetFileNameWithoutExtension(source.SourceDocument)}Handler.cs", fileContent);

                    //Clearing model store for the next call
                    store = null;
                }

                //Create a class file in the Modules folder from a T4 Template for each model class
                foreach (CsSource source in moduleClasses)
                {
                    store = new CsModelStore();
                    store.SetModel(source);
                    await _visualStudioActions.ProjectFolderActions.AddDocumentAsync(modulesFolder, $"{Path.GetFileNameWithoutExtension(source.SourceDocument)}Handler.cs", ModuleFactory.GenerateSource(store, conversionData));

                    store = null;
                }

                //Completed process the modules informing the dialog it has passed.
                await _statusTracking.UpdateStepStatusAsync(MigrationStepEnum.HttpModules, MigrationStatusEnum.Passed);
            }
            catch (Exception unhandledError)
            {
                //Dumping the exception that occured directly into the status so the user can see what happened.
                await _statusTracking.UpdateCurrentStatusAsync(MigrationStepEnum.HttpModules, MessageTypeEnum.Error, $"The following unhandled error occured. '{unhandledError.Message}'");

                //Updating the status that the step failed
                await _statusTracking.UpdateStepStatusAsync(MigrationStepEnum.HttpModules, MigrationStatusEnum.Failed);
            }
        }
        /// <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}'");
            }
        }