using Microsoft.AspNetCore.Razor.Language; using System.Collections.Generic; namespace Sandbox.Razor; public static class RazorProcessor { /// /// Generate the c# code from an incoming razor file /// public static string GenerateFromSource( string text, string filename, string rootNamespace = null, bool useFolderNamespacing = true ) { // If a root namespace is provided and the file doesn't have an namespace inject one if ( useFolderNamespacing ) { text = AddNamespace( text, filename, rootNamespace ); } var engine = GetEngine(); RazorSourceDocument source = RazorSourceDocument.Create( text, filename ); RazorCodeDocument code = engine.Process( source, FileKinds.Component, new List(), new List() ); code.SetCodeGenerationOptions( RazorCodeGenerationOptions.Create( o => { } ) ); RazorCSharpDocument document = code.GetCSharpDocument(); return document.GeneratedCode; } private static string AddNamespace( string text, string filename, string rootNamespace ) { if ( string.IsNullOrEmpty( rootNamespace ) ) return text; if ( text.Contains( "@namespace" ) ) return text; // Compute namespace from folder structure var directory = System.IO.Path.GetDirectoryName( filename ); var computedNamespace = rootNamespace; if ( !string.IsNullOrEmpty( directory ) ) { // Normalize path separators to forward slash directory = directory.Replace( '\\', '/' ); // Split by path separator and filter out empty or invalid segments var folders = directory.Split( ['/'], System.StringSplitOptions.RemoveEmptyEntries ); foreach ( var folder in folders ) { // Only include folders that would make valid C# namespace identifiers if ( IsValidNamespaceSegment( folder ) ) { computedNamespace += "." + folder; } } } return $"@namespace {computedNamespace}\n{text}"; } /// /// Check if a folder name is valid as a C# namespace segment /// static bool IsValidNamespaceSegment( string segment ) { if ( string.IsNullOrWhiteSpace( segment ) ) return false; if ( segment.Contains( ":" ) ) return false; if ( segment == "." || segment == ".." ) return false; if ( segment.Contains( " " ) || segment.Contains( "-" ) ) return false; if ( char.IsDigit( segment[0] ) ) return false; return true; } static RazorProjectEngine GetEngine() { var configuration = RazorConfiguration.Default; var razorProjectEngine = RazorProjectEngine.Create( configuration, RazorProjectFileSystem.Create( "." ) ); return razorProjectEngine; } }