From d1b27ed8fbbb12844aacbcaab79fec904194cf42 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Fri, 2 Jan 2026 23:24:32 +0100 Subject: [PATCH 01/15] .net 10 upgrade --- .github/workflows/dotnet-test.yml | 2 +- .github/workflows/publish-nuget.yml | 2 +- Directory.Build.props | 2 +- README.md | 48 +++------ README.source.md | 8 +- RazorLight.sln | 97 ------------------- RazorLight.slnx | 34 +++++++ .../FunctionApp-WebMvc-Sample.csproj | 6 +- .../Samples.EntityFrameworkProject.csproj | 4 +- .../RazorLight.Precompile.csproj | 6 +- .../Razor/FileSystemRazorProject.cs | 8 +- src/RazorLight/RazorLight.csproj | 16 +-- .../FileSystemCachingStrategyTests.cs | 8 +- tests/RazorLight.Precompile.Tests/Helper.cs | 2 +- .../PrecompileTests.cs | 14 +-- .../RazorLight.Precompile.Tests.csproj | 20 ++-- .../Render1Tests.cs | 4 +- .../Render2Tests.cs | 8 +- .../Compilation/RazorTemplateCompilerTest.cs | 4 +- .../Integration/RendererCommonCasesTests.cs | 4 +- .../Razor/EmbeddedRazorProjectTest.cs | 4 +- .../Razor/FileSystemRazorProjectTest.cs | 4 +- .../RazorLight.Tests/RazorLight.Tests.csproj | 25 ++--- 23 files changed, 125 insertions(+), 205 deletions(-) delete mode 100644 RazorLight.sln create mode 100644 RazorLight.slnx diff --git a/.github/workflows/dotnet-test.yml b/.github/workflows/dotnet-test.yml index b89d75ef..52e6b7e8 100644 --- a/.github/workflows/dotnet-test.yml +++ b/.github/workflows/dotnet-test.yml @@ -20,7 +20,7 @@ jobs: - name: Setup DotNet ✨ uses: actions/setup-dotnet@v5 with: - dotnet-version: "9.0.x" + dotnet-version: "10.0.x" - name: Install dependencies 📦️ run: dotnet restore diff --git a/.github/workflows/publish-nuget.yml b/.github/workflows/publish-nuget.yml index ad4a5348..91e88f36 100644 --- a/.github/workflows/publish-nuget.yml +++ b/.github/workflows/publish-nuget.yml @@ -21,7 +21,7 @@ jobs: - name: Setup DotNet ✨ uses: actions/setup-dotnet@v5 with: - dotnet-version: "9.0.x" + dotnet-version: "10.0.x" - name: Install dependencies 📦️ run: dotnet restore diff --git a/Directory.Build.props b/Directory.Build.props index e6b161b1..9edc83ea 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -17,7 +17,7 @@ - + diff --git a/README.md b/README.md index b19af6d4..22a65f31 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,11 @@ To change this file edit the source file and then run MarkdownSnippets. # RazorLight -Use Razor to build templates from Files / EmbeddedResources / Strings / Database or your custom source outside of ASP.NET MVC. No redundant dependencies and workarounds in pair with excellent performance and **.NET 8.0 and .NET 9.0** support. +Use Razor to build templates from Files / EmbeddedResources / Strings / Database or your custom source outside of ASP.NET MVC. No redundant dependencies and workarounds in pair with excellent performance and **.NET 8.0, NET 9.0 and .NET 10.0** support. Forked from original by [@toddams](https://github.com/toddams/RazorLight/) -My packages are the same names, but prefixed with jcamp. to differentiate them. +My packages are the same names, but prefixed with `jcamp.` to differentiate them. The original repo has not been updated in two years and I needed some updates to the package that were provided by various PRs. I've tried to give all credit where due. @@ -34,16 +34,14 @@ The original repo has not been updated in two years and I needed some updates to Install the nuget package using following command: -``` +```pws Install-Package RazorLight -Version 3.0.0 ``` The simplest scenario is to create a template from string. Each template must have a `templateKey` that is associated with it, so you can render the same template next time without recompilation. - - - - + + ```cs var engine = new RazorLightEngineBuilder() // required to have a default RazorLightProject type, @@ -58,17 +56,13 @@ ViewModel model = new ViewModel {Name = "John Doe"}; string result = await engine.CompileRenderStringAsync("templateKey", template, model); ``` - -snippet source | anchor - +snippet source | anchor To render a compiled template: - - - + ```cs var cacheResult = engine.Handler.Cache.RetrieveTemplate("templateKey"); if(cacheResult.Success) @@ -77,9 +71,7 @@ if(cacheResult.Success) string result = await engine.RenderTemplateAsync(templatePage, model); } ``` - -snippet source | anchor - +snippet source | anchor # Template sources @@ -91,9 +83,7 @@ RazorLight can resolve templates from any source, but there are a built-in provi When resolving a template from filesystem, templateKey - is a relative path to the root folder, that you pass to RazorLightEngineBuilder. - - - + ```cs var engine = new RazorLightEngineBuilder() .UseFileSystemProject("C:/RootFolder/With/YourTemplates") @@ -103,9 +93,7 @@ var engine = new RazorLightEngineBuilder() var model = new {Name = "John Doe"}; string result = await engine.CompileRenderAsync("Subfolder/View.cshtml", model); ``` - -snippet source | anchor - +snippet source | anchor ## EmbeddedResource source @@ -127,9 +115,7 @@ Project.Core/ ``` - - - + ```cs var engine = new RazorLightEngineBuilder() .UseEmbeddedResourcesProject(typeof(SomeService).Assembly) @@ -139,17 +125,13 @@ var engine = new RazorLightEngineBuilder() var model = new Model(); string html = await engine.CompileRenderAsync("EmailTemplates.Body", model); ``` - -snippet source | anchor - +snippet source | anchor Setting the root namespace allows you to leave that piece off when providing the template name as the key: - - - + ```cs var engine = new RazorLightEngineBuilder() .UseEmbeddedResourcesProject(typeof(SomeService).Assembly, "Project.Core.EmailTemplates") @@ -159,9 +141,7 @@ var engine = new RazorLightEngineBuilder() var model = new Model(); string html = await engine.CompileRenderAsync("Body", model); ``` - -snippet source | anchor - +snippet source | anchor ## Custom source diff --git a/README.source.md b/README.source.md index 3c8f303f..1aef9a81 100644 --- a/README.source.md +++ b/README.source.md @@ -2,11 +2,11 @@ # RazorLight -Use Razor to build templates from Files / EmbeddedResources / Strings / Database or your custom source outside of ASP.NET MVC. No redundant dependencies and workarounds in pair with excellent performance and **.NET 8.0 and .NET 9.0** support. +Use Razor to build templates from Files / EmbeddedResources / Strings / Database or your custom source outside of ASP.NET MVC. No redundant dependencies and workarounds in pair with excellent performance and **.NET 8.0, NET 9.0 and .NET 10.0** support. Forked from original by [@toddams](https://github.com/toddams/RazorLight/) -My packages are the same names, but prefixed with jcamp. to differentiate them. +My packages are the same names, but prefixed with `jcamp.` to differentiate them. The original repo has not been updated in two years and I needed some updates to the package that were provided by various PRs. I've tried to give all credit where due. @@ -27,13 +27,13 @@ The original repo has not been updated in two years and I needed some updates to Install the nuget package using following command: -``` +```pws Install-Package RazorLight -Version 3.0.0 ``` The simplest scenario is to create a template from string. Each template must have a `templateKey` that is associated with it, so you can render the same template next time without recompilation. -snippet: simple +snippet: Simple To render a compiled template: diff --git a/RazorLight.sln b/RazorLight.sln deleted file mode 100644 index 8968e6ca..00000000 --- a/RazorLight.sln +++ /dev/null @@ -1,97 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.2.32616.157 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{25F57564-58FD-4FD2-8CDA-98261E5BEEEC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{CDB1D407-71F7-44D6-8B35-F0013D1717A6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorLight", "src\RazorLight\RazorLight.csproj", "{CA780663-2714-43B0-89BC-BEB26BC5405A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sandbox", "sandbox", "{D8281EA5-1C64-4C9F-9537-967D685C1918}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorLight.Sandbox", "sandbox\RazorLight.Sandbox\RazorLight.Sandbox.csproj", "{DC81E072-5571-4E4A-A7EC-4122BF4A012E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorLight.Tests", "tests\RazorLight.Tests\RazorLight.Tests.csproj", "{63EE1F3F-C71E-48DA-8135-9E602D6B7206}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{61D04B29-43F8-4FE3-A12E-BB16743BFB65}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.EntityFrameworkProject", "samples\RazorLight.Samples\Samples.EntityFrameworkProject.csproj", "{C9B26DF6-F8E6-481A-B497-C8999641A99D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorLight.Precompile", "src\RazorLight.Precompile\RazorLight.Precompile.csproj", "{AD9A02F6-8078-4DFF-AFA6-4DE8674D5C76}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External", "External", "{634B4E56-928A-4132-AB3F-F2DD43756350}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - LICENSE = LICENSE - README.md = README.md - README.source.md = README.source.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{DF8F9896-63C0-43AC-8834-1D13AA095928}" - ProjectSection(SolutionItems) = preProject - Directory.Build.props = Directory.Build.props - .github\workflows\dotnet-test.yml = .github\workflows\dotnet-test.yml - .github\workflows\publish-nuget.yml = .github\workflows\publish-nuget.yml - .github\workflows\release-please.yml = .github\workflows\release-please.yml - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Publish", "Publish", "{03C519A7-C5B1-4421-893B-D2995D4A92BC}" - ProjectSection(SolutionItems) = preProject - makeNuget.cmd = makeNuget.cmd - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EC25D85F-CCCC-43E1-AACD-2D710C1B760B}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorLight.Precompile.Tests", "tests\RazorLight.Precompile.Tests\RazorLight.Precompile.Tests.csproj", "{C9BA26CD-C20E-493C-A55A-C5498778184B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CA780663-2714-43B0-89BC-BEB26BC5405A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CA780663-2714-43B0-89BC-BEB26BC5405A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CA780663-2714-43B0-89BC-BEB26BC5405A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CA780663-2714-43B0-89BC-BEB26BC5405A}.Release|Any CPU.Build.0 = Release|Any CPU - {DC81E072-5571-4E4A-A7EC-4122BF4A012E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DC81E072-5571-4E4A-A7EC-4122BF4A012E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DC81E072-5571-4E4A-A7EC-4122BF4A012E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DC81E072-5571-4E4A-A7EC-4122BF4A012E}.Release|Any CPU.Build.0 = Release|Any CPU - {63EE1F3F-C71E-48DA-8135-9E602D6B7206}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {63EE1F3F-C71E-48DA-8135-9E602D6B7206}.Debug|Any CPU.Build.0 = Debug|Any CPU - {63EE1F3F-C71E-48DA-8135-9E602D6B7206}.Release|Any CPU.ActiveCfg = Release|Any CPU - {63EE1F3F-C71E-48DA-8135-9E602D6B7206}.Release|Any CPU.Build.0 = Release|Any CPU - {C9B26DF6-F8E6-481A-B497-C8999641A99D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C9B26DF6-F8E6-481A-B497-C8999641A99D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C9B26DF6-F8E6-481A-B497-C8999641A99D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C9B26DF6-F8E6-481A-B497-C8999641A99D}.Release|Any CPU.Build.0 = Release|Any CPU - {AD9A02F6-8078-4DFF-AFA6-4DE8674D5C76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AD9A02F6-8078-4DFF-AFA6-4DE8674D5C76}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD9A02F6-8078-4DFF-AFA6-4DE8674D5C76}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AD9A02F6-8078-4DFF-AFA6-4DE8674D5C76}.Release|Any CPU.Build.0 = Release|Any CPU - {C9BA26CD-C20E-493C-A55A-C5498778184B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C9BA26CD-C20E-493C-A55A-C5498778184B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C9BA26CD-C20E-493C-A55A-C5498778184B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C9BA26CD-C20E-493C-A55A-C5498778184B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {CA780663-2714-43B0-89BC-BEB26BC5405A} = {25F57564-58FD-4FD2-8CDA-98261E5BEEEC} - {DC81E072-5571-4E4A-A7EC-4122BF4A012E} = {D8281EA5-1C64-4C9F-9537-967D685C1918} - {63EE1F3F-C71E-48DA-8135-9E602D6B7206} = {CDB1D407-71F7-44D6-8B35-F0013D1717A6} - {C9B26DF6-F8E6-481A-B497-C8999641A99D} = {61D04B29-43F8-4FE3-A12E-BB16743BFB65} - {AD9A02F6-8078-4DFF-AFA6-4DE8674D5C76} = {25F57564-58FD-4FD2-8CDA-98261E5BEEEC} - {C9BA26CD-C20E-493C-A55A-C5498778184B} = {CDB1D407-71F7-44D6-8B35-F0013D1717A6} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {590C5541-E5A7-41ED-AFC7-D4A52E594191} - EndGlobalSection -EndGlobal diff --git a/RazorLight.slnx b/RazorLight.slnx new file mode 100644 index 00000000..3208197e --- /dev/null +++ b/RazorLight.slnx @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/FunctionApp-WebMvc-Sample/FunctionApp-WebMvc-Sample/FunctionApp-WebMvc-Sample.csproj b/samples/FunctionApp-WebMvc-Sample/FunctionApp-WebMvc-Sample/FunctionApp-WebMvc-Sample.csproj index 74b69d75..655a6002 100644 --- a/samples/FunctionApp-WebMvc-Sample/FunctionApp-WebMvc-Sample/FunctionApp-WebMvc-Sample.csproj +++ b/samples/FunctionApp-WebMvc-Sample/FunctionApp-WebMvc-Sample/FunctionApp-WebMvc-Sample.csproj @@ -13,10 +13,10 @@ - + - - + + diff --git a/samples/RazorLight.Samples/Samples.EntityFrameworkProject.csproj b/samples/RazorLight.Samples/Samples.EntityFrameworkProject.csproj index 30340583..7ccad352 100644 --- a/samples/RazorLight.Samples/Samples.EntityFrameworkProject.csproj +++ b/samples/RazorLight.Samples/Samples.EntityFrameworkProject.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/src/RazorLight.Precompile/RazorLight.Precompile.csproj b/src/RazorLight.Precompile/RazorLight.Precompile.csproj index c471f4bc..e0209042 100644 --- a/src/RazorLight.Precompile/RazorLight.Precompile.csproj +++ b/src/RazorLight.Precompile/RazorLight.Precompile.csproj @@ -2,7 +2,7 @@ Exe - net8.0;net9.0 + net8.0;net9.0;net10.0 razorlight-precompile true true @@ -14,8 +14,8 @@ - - + + diff --git a/src/RazorLight/Razor/FileSystemRazorProject.cs b/src/RazorLight/Razor/FileSystemRazorProject.cs index 46e4a248..07ebb5f9 100644 --- a/src/RazorLight/Razor/FileSystemRazorProject.cs +++ b/src/RazorLight/Razor/FileSystemRazorProject.cs @@ -3,11 +3,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using System.Threading.Tasks; namespace RazorLight.Razor -{ +{ /// /// Specifies RazorProject where templates are located in files /// @@ -43,6 +42,11 @@ public FileSystemRazorProject(string root, string extension) /// public override Task GetItemAsync(string templateKey) { + if (string.IsNullOrEmpty(templateKey)) + { + throw new ArgumentNullException(nameof(templateKey)); + } + if (!templateKey.EndsWith(Extension)) { templateKey = templateKey + Extension; diff --git a/src/RazorLight/RazorLight.csproj b/src/RazorLight/RazorLight.csproj index 3c8a3994..caca786d 100644 --- a/src/RazorLight/RazorLight.csproj +++ b/src/RazorLight/RazorLight.csproj @@ -1,6 +1,6 @@ - net8.0;net9.0 + net8.0;net9.0;net10.0 latest @@ -31,16 +31,16 @@ - + - - - - - - + + + + + + diff --git a/tests/RazorLight.Precompile.Tests/FileSystemCachingStrategyTests.cs b/tests/RazorLight.Precompile.Tests/FileSystemCachingStrategyTests.cs index 8ed30eee..2e9d2f3d 100644 --- a/tests/RazorLight.Precompile.Tests/FileSystemCachingStrategyTests.cs +++ b/tests/RazorLight.Precompile.Tests/FileSystemCachingStrategyTests.cs @@ -57,14 +57,14 @@ public void DifferentKey(IFileSystemCachingStrategy s) var templateFilePath = "Samples/folder/MessageItem.cshtml"; var o1 = s.GetCachedFileInfo("folder/MessageItem.cshtml", templateFilePath, "X:/"); var o2 = s.GetCachedFileInfo("MessageItem.cshtml", templateFilePath, "X:/"); - Assert.AreNotEqual(o1.AssemblyFilePath, o2.AssemblyFilePath); + Assert.That(o1.AssemblyFilePath, Is.Not.EqualTo(o2.AssemblyFilePath)); } [TestCaseSource(nameof(s_sepCombinations))] public void EquivalentKeyFileHashCachingStrategy(string[] sepCombination) { var (asmFilePath1, asmFilePath2) = GetAsmFilePaths(FileHashCachingStrategy.Instance, sepCombination); - Assert.AreEqual(asmFilePath1, asmFilePath2); + Assert.That(asmFilePath1, Is.EqualTo(asmFilePath2)); } [TestCaseSource(nameof(s_sepCombinations))] @@ -76,7 +76,7 @@ public void EquivalentKeySimpleFileCachingStrategy(string[] sepCombination) asmFilePath1 = Path.GetFullPath(asmFilePath1); asmFilePath2 = Path.GetFullPath(asmFilePath2); } - Assert.AreEqual(asmFilePath1, asmFilePath2); + Assert.That(asmFilePath1, Is.EqualTo(asmFilePath2)); } private static (string, string) GetAsmFilePaths(IFileSystemCachingStrategy s, string[] sepCombination) @@ -84,7 +84,7 @@ private static (string, string) GetAsmFilePaths(IFileSystemCachingStrategy s, st var templateFilePath = "Samples/folder/MessageItem.cshtml"; string key1 = $"{sepCombination[0]}folder{sepCombination[1]}MessageItem.cshtml"; string key2 = $"{sepCombination[2]}folder{sepCombination[3]}MessageItem.cshtml"; - Assert.AreNotEqual(key1, key2); + Assert.That(key1, Is.Not.EqualTo(key2)); var asmFilePath1 = s.GetCachedFileInfo(key1, templateFilePath, "X:/").AssemblyFilePath; var asmFilePath2 = s.GetCachedFileInfo(key2, templateFilePath, "X:/").AssemblyFilePath; return (asmFilePath1, asmFilePath2); diff --git a/tests/RazorLight.Precompile.Tests/Helper.cs b/tests/RazorLight.Precompile.Tests/Helper.cs index 3a0d9db6..4a6ae0f1 100644 --- a/tests/RazorLight.Precompile.Tests/Helper.cs +++ b/tests/RazorLight.Precompile.Tests/Helper.cs @@ -17,7 +17,7 @@ public static StringBuilder RunCommand(params string[] args) var sw = new StringWriter(); Program.ConsoleOut = sw; var exitCode = Program.DoRun(args); - Assert.Zero(exitCode); + Assert.That(exitCode, Is.Zero); sw.Close(); return sw.GetStringBuilder(); diff --git a/tests/RazorLight.Precompile.Tests/PrecompileTests.cs b/tests/RazorLight.Precompile.Tests/PrecompileTests.cs index 1841c3ce..cdce43ee 100644 --- a/tests/RazorLight.Precompile.Tests/PrecompileTests.cs +++ b/tests/RazorLight.Precompile.Tests/PrecompileTests.cs @@ -11,12 +11,12 @@ public void PrecompileFromScratch(string templateFilePath, TestScenario scenario scenario.Cleanup(); var expectedPrecompiledFilePath = GetExpectedPrecompiledFilePath(templateFilePath, scenario); - FileAssert.DoesNotExist(expectedPrecompiledFilePath); + Assert.That(expectedPrecompiledFilePath, Does.Not.Exist); Precompile(templateFilePath, scenario, expectedPrecompiledFilePath); scenario.Cleanup(); - FileAssert.DoesNotExist(expectedPrecompiledFilePath); + Assert.That(expectedPrecompiledFilePath, Does.Not.Exist); } [TestCaseSource(typeof(PrecompileTestCases), nameof(PrecompileTestCases.TestCases))] @@ -25,13 +25,13 @@ public void PrecompileCached(string templateFilePath, TestScenario scenario) scenario.Cleanup(); var expectedPrecompiledFilePath = GetExpectedPrecompiledFilePath(templateFilePath, scenario); - FileAssert.DoesNotExist(expectedPrecompiledFilePath); + Assert.That(expectedPrecompiledFilePath, Does.Not.Exist); var sw1 = Stopwatch.StartNew(); Precompile(templateFilePath, scenario, expectedPrecompiledFilePath); sw1.Stop(); - FileAssert.Exists(expectedPrecompiledFilePath); + Assert.That(expectedPrecompiledFilePath, Does.Exist); var sw2 = Stopwatch.StartNew(); Precompile(templateFilePath, scenario, expectedPrecompiledFilePath); @@ -40,7 +40,7 @@ public void PrecompileCached(string templateFilePath, TestScenario scenario) TestContext.WriteLine($"TS1 = {sw1.Elapsed}, TS2 = {sw2.Elapsed}"); scenario.Cleanup(); - FileAssert.DoesNotExist(expectedPrecompiledFilePath); + Assert.That(expectedPrecompiledFilePath, Does.Not.Exist); } public static string GetExpectedPrecompiledFilePath(string templateFilePath, TestScenario scenario) @@ -60,8 +60,8 @@ public static void Precompile(string templateFilePath, TestScenario scenario, st commandLineArgs.AddRange(scenario.ExtraCommandLineArgs); var precompiledFilePath = Helper.RunCommandTrimNewline(commandLineArgs.ToArray()); - Assert.AreEqual(expectedPrecompiledFilePath, precompiledFilePath); - FileAssert.Exists(precompiledFilePath); + Assert.That(precompiledFilePath, Is.EqualTo(expectedPrecompiledFilePath)); + Assert.That(precompiledFilePath, Does.Exist); } } } \ No newline at end of file diff --git a/tests/RazorLight.Precompile.Tests/RazorLight.Precompile.Tests.csproj b/tests/RazorLight.Precompile.Tests/RazorLight.Precompile.Tests.csproj index d16e99d1..ed243436 100644 --- a/tests/RazorLight.Precompile.Tests/RazorLight.Precompile.Tests.csproj +++ b/tests/RazorLight.Precompile.Tests/RazorLight.Precompile.Tests.csproj @@ -1,18 +1,18 @@ - - net8.0;net9.0 - true - enable - enable - CS8600;CS8602;CS8603;CS8604 - latest + + net8.0;net9.0;net10.0 + true + enable + enable + CS8600;CS8602;CS8603;CS8604 + latest - - - + + + diff --git a/tests/RazorLight.Precompile.Tests/Render1Tests.cs b/tests/RazorLight.Precompile.Tests/Render1Tests.cs index fdd07545..06eb37bf 100644 --- a/tests/RazorLight.Precompile.Tests/Render1Tests.cs +++ b/tests/RazorLight.Precompile.Tests/Render1Tests.cs @@ -90,7 +90,7 @@ public void Render(string templateFilePath, string jsonQuery, string expected) } var actual = Helper.RunCommand(commandLineArgs.ToArray()).ToString(); - Assert.AreEqual(expected, actual); + Assert.That(actual, Is.EqualTo(expected)); } [TestCaseSource(nameof(s_testCases))] @@ -112,7 +112,7 @@ public void PrecompileAndRender(string templateFilePath, string jsonQuery, strin } var actual = Helper.RunCommand(commandLineArgs.ToArray()).ToString(); - Assert.AreEqual(expected, actual); + Assert.That(actual, Is.EqualTo(expected)); } } } \ No newline at end of file diff --git a/tests/RazorLight.Precompile.Tests/Render2Tests.cs b/tests/RazorLight.Precompile.Tests/Render2Tests.cs index f6858946..504ca054 100644 --- a/tests/RazorLight.Precompile.Tests/Render2Tests.cs +++ b/tests/RazorLight.Precompile.Tests/Render2Tests.cs @@ -102,7 +102,7 @@ public void RenderFolderNonRecursive(string key, string key2, IFileSystemCaching Precompile(key, key2, s); var exc = Assert.Throws(() => Run(key, expected, "Samples")); - Assert.AreEqual("No precompiled template found for the key /folder/MessageItem.cshtml", exc.Message); + Assert.That(exc.Message, Is.EqualTo("No precompiled template found for the key /folder/MessageItem.cshtml")); } [TestCaseSource(nameof(s_testCases))] @@ -111,7 +111,7 @@ public void RenderGlobNonRecursive(string key, string key2, IFileSystemCachingSt Precompile(key, key2, s); var exc = Assert.Throws(() => Run(key, expected, "Samples/*.dll")); - Assert.AreEqual("No precompiled template found for the key /folder/MessageItem.cshtml", exc.Message); + Assert.That(exc.Message, Is.EqualTo("No precompiled template found for the key /folder/MessageItem.cshtml")); } private static (string, string) Precompile(string key, string key2, IFileSystemCachingStrategy s) => ( @@ -134,7 +134,7 @@ private static void Run(string key, string expected, string precompiledFilePath, commandLineArgs.AddRange(args); var actual = Helper.RunCommand(commandLineArgs.ToArray()).ToString(); - Assert.AreEqual(expected, actual); + Assert.That(actual, Is.EqualTo(expected)); } [TestCaseSource(nameof(s_testCases))] @@ -154,7 +154,7 @@ public void PrecompileAndRender(string templateFilePath, string _, IFileSystemCa }; var actual = Helper.RunCommand(commandLineArgs.ToArray()).ToString(); - Assert.AreEqual(expected, actual); + Assert.That(actual, Is.EqualTo(expected)); } } } \ No newline at end of file diff --git a/tests/RazorLight.Tests/Compilation/RazorTemplateCompilerTest.cs b/tests/RazorLight.Tests/Compilation/RazorTemplateCompilerTest.cs index 280cebae..857269a7 100644 --- a/tests/RazorLight.Tests/Compilation/RazorTemplateCompilerTest.cs +++ b/tests/RazorLight.Tests/Compilation/RazorTemplateCompilerTest.cs @@ -117,14 +117,14 @@ public async Task Compiler_Searches_WithNormalizedKey_IfNotFound() } [Fact] - public void Throws_TemplateNotFoundException_If_ProjectItem_NotExist() + public async Task Throws_TemplateNotFoundException_If_ProjectItem_NotExist() { var project = new EmbeddedRazorProject(typeof(Root).Assembly); var compiler = TestRazorTemplateCompiler.Create(project: project); Func task = new Func(() => compiler.CompileAsync("Not.Existing.Key")); - Assert.ThrowsAsync(task); + await Assert.ThrowsAsync(task); } [Fact] diff --git a/tests/RazorLight.Tests/Integration/RendererCommonCasesTests.cs b/tests/RazorLight.Tests/Integration/RendererCommonCasesTests.cs index 7c787eb9..7dae6a62 100644 --- a/tests/RazorLight.Tests/Integration/RendererCommonCasesTests.cs +++ b/tests/RazorLight.Tests/Integration/RendererCommonCasesTests.cs @@ -1,5 +1,4 @@ -using System; -using System.IO; +using System.IO; using System.Threading.Tasks; using RazorLight.Tests.Utils; using VerifyXunit; @@ -14,7 +13,6 @@ public class TestViewModel public int NumberOfItems { get; set; } } - [UsesVerify] public class RendererCommonCasesTests { diff --git a/tests/RazorLight.Tests/Razor/EmbeddedRazorProjectTest.cs b/tests/RazorLight.Tests/Razor/EmbeddedRazorProjectTest.cs index 0d6521ed..1793a354 100644 --- a/tests/RazorLight.Tests/Razor/EmbeddedRazorProjectTest.cs +++ b/tests/RazorLight.Tests/Razor/EmbeddedRazorProjectTest.cs @@ -17,11 +17,11 @@ public void Ensure_Throws_OnNullRootType() } [Fact] - public void Ensure_Throws_OnNullTemplateKey() + public async Task Ensure_Throws_OnNullTemplateKey() { var project = new EmbeddedRazorProject(typeof(EmbeddedRazorProject)); - Assert.ThrowsAsync(async () => { await project.GetItemAsync(null); }); + await Assert.ThrowsAsync(() => project.GetItemAsync(null)); } [Fact] diff --git a/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs b/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs index f01b19cd..991c2a91 100644 --- a/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs +++ b/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs @@ -50,11 +50,11 @@ public void Ensure_ExtensionProperty_AssignedOnConstructor() } [Fact] - public void Null_TemplateKey_ThrowsOn_GetItem() + public async Task Null_TemplateKey_ThrowsOn_GetItem() { var project = new FileSystemRazorProject(DirectoryUtils.RootDirectory); - Assert.ThrowsAsync(async () => await project.GetItemAsync("not-existing-key")); + await Assert.ThrowsAsync(() => project.GetItemAsync(null)); } [Fact] diff --git a/tests/RazorLight.Tests/RazorLight.Tests.csproj b/tests/RazorLight.Tests/RazorLight.Tests.csproj index a1812a0b..27d0bcb3 100644 --- a/tests/RazorLight.Tests/RazorLight.Tests.csproj +++ b/tests/RazorLight.Tests/RazorLight.Tests.csproj @@ -1,7 +1,7 @@ - net8.0;net9.0 + net8.0;net9.0;net10.0 false true $(DefineConstants);SOME_TEST_DEFINE @@ -36,13 +36,13 @@ - - + + - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -51,14 +51,15 @@ - + - - - - + + + + + From 8ada2a4d8ae99f2ab27c080f6be5e5133eff44d9 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Fri, 2 Jan 2026 23:56:40 +0100 Subject: [PATCH 02/15] fix compilation warnings for test project --- .../Caching/DefaultCachingProviderTest.cs | 14 ++++++-------- .../Compilation/RoslynCompilerServiceTest.cs | 4 ++-- .../TemplateCompilationExceptionTests.cs | 8 ++++---- .../Extensions/ServiceCollectionExtensionsTest.cs | 4 ++-- .../Razor/FileSystemRazorProjectTest.cs | 2 +- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/tests/RazorLight.Tests/Caching/DefaultCachingProviderTest.cs b/tests/RazorLight.Tests/Caching/DefaultCachingProviderTest.cs index 26357001..47654d72 100644 --- a/tests/RazorLight.Tests/Caching/DefaultCachingProviderTest.cs +++ b/tests/RazorLight.Tests/Caching/DefaultCachingProviderTest.cs @@ -1,6 +1,7 @@ using Moq; using RazorLight.Caching; using System; +using System.Threading.Tasks; using Xunit; namespace RazorLight.Tests.Caching @@ -70,7 +71,7 @@ public void Returns_EmptyTemplateCacheResult_OnNonExistingTemplate() } [Fact] - public void Respects_DisabledEncoding_On_CachedTemplates() + public async Task Respects_DisabledEncoding_On_CachedTemplates() { string templateKey = "Assets.Embedded.Empty.cshtml"; @@ -79,16 +80,13 @@ public void Respects_DisabledEncoding_On_CachedTemplates() .UseMemoryCachingProvider() .SetOperatingAssembly(typeof(Root).Assembly) .UseEmbeddedResourcesProject(typeof(Root)) - .Build(); - var testCompileToCache = engine.CompileTemplateAsync(templateKey).Result; - + + var testCompileToCache = await engine.CompileTemplateAsync(templateKey); Assert.True(testCompileToCache.DisableEncoding); - - var cachedCompile = engine.CompileTemplateAsync(templateKey).Result; - + + var cachedCompile = await engine.CompileTemplateAsync(templateKey); Assert.True(cachedCompile.DisableEncoding); - } private Func GetTestFactory(string key = "key") diff --git a/tests/RazorLight.Tests/Compilation/RoslynCompilerServiceTest.cs b/tests/RazorLight.Tests/Compilation/RoslynCompilerServiceTest.cs index d777ff04..70e8d159 100644 --- a/tests/RazorLight.Tests/Compilation/RoslynCompilerServiceTest.cs +++ b/tests/RazorLight.Tests/Compilation/RoslynCompilerServiceTest.cs @@ -276,8 +276,8 @@ public void Throw_With_CompilationErrors_On_Failed_BuildAsync() var ex = Assert.Throws(() => compiler.CompileAndEmit(template)); Assert.NotEmpty(ex.CompilationErrors); Assert.NotEmpty(ex.CompilationDiagnostics); - Assert.Equal(1, ex.CompilationDiagnostics.Count); - Assert.Equal(1, ex.CompilationErrors.Count); + Assert.Single(ex.CompilationDiagnostics); + Assert.Single(ex.CompilationErrors); } [Fact] diff --git a/tests/RazorLight.Tests/Compilation/TemplateCompilationExceptionTests.cs b/tests/RazorLight.Tests/Compilation/TemplateCompilationExceptionTests.cs index 508abb83..0f3e94b5 100644 --- a/tests/RazorLight.Tests/Compilation/TemplateCompilationExceptionTests.cs +++ b/tests/RazorLight.Tests/Compilation/TemplateCompilationExceptionTests.cs @@ -19,8 +19,8 @@ public void Ensure_CompilationDiagnostics_FormattedMessage_Matches_CompilationEr Assert.NotEmpty(exception.CompilationDiagnostics); Assert.NotEmpty(exception.CompilationErrors); - Assert.Equal(1, exception.CompilationDiagnostics.Count); - Assert.Equal(1, exception.CompilationErrors.Count); + Assert.Single(exception.CompilationDiagnostics); + Assert.Single(exception.CompilationErrors); var firstDiagnostic = exception.CompilationDiagnostics[0]; Assert.Equal("diagnosticMessage",firstDiagnostic.ErrorMessage); @@ -45,8 +45,8 @@ public void Ensure_InitalizedWtihErrors_FormattedMessage_Matches_CompilationErro Assert.NotEmpty(exception.CompilationDiagnostics); Assert.NotEmpty(exception.CompilationErrors); - Assert.Equal(1, exception.CompilationDiagnostics.Count); - Assert.Equal(1, exception.CompilationErrors.Count); + Assert.Single(exception.CompilationDiagnostics); + Assert.Single(exception.CompilationErrors); var firstDiagnostic = exception.CompilationDiagnostics[0]; Assert.Equal("formattedMessage",firstDiagnostic.ErrorMessage); diff --git a/tests/RazorLight.Tests/Extensions/ServiceCollectionExtensionsTest.cs b/tests/RazorLight.Tests/Extensions/ServiceCollectionExtensionsTest.cs index 7c61afc8..85c9d61b 100644 --- a/tests/RazorLight.Tests/Extensions/ServiceCollectionExtensionsTest.cs +++ b/tests/RazorLight.Tests/Extensions/ServiceCollectionExtensionsTest.cs @@ -254,7 +254,7 @@ public void Ensure_RazorLightEngineWithFileSystemFactory_Is_Called() } [Fact] - public void Ensure_DI_Extension_Can_Inject() + public async Task Ensure_DI_Extension_Can_Inject() { var services = GetServices(); bool newRazorLightEngineCalled = false; @@ -287,7 +287,7 @@ public void Ensure_DI_Extension_Can_Inject() var engine = provider.GetService(); Assert.NotNull(engine); Assert.IsType(engine); - engine.CompileRenderStringAsync("","","").GetAwaiter().GetResult(); + await engine.CompileRenderStringAsync("","",""); Assert.True(newRazorLightEngineCalled); Assert.IsType(provider.GetService()); diff --git a/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs b/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs index 991c2a91..d8da95b4 100644 --- a/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs +++ b/tests/RazorLight.Tests/Razor/FileSystemRazorProjectTest.cs @@ -35,7 +35,7 @@ public void Ensure_ExtensionProperty_IsDefaultIfNotProvided() var project = new FileSystemRazorProject(root); - Assert.Equal(project.Extension, FileSystemRazorProject.DefaultExtension); + Assert.Equal(FileSystemRazorProject.DefaultExtension, project.Extension); } [Fact] From 123e7e74b1c5089571ac9603e76590899ff4e202 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:12:49 +0100 Subject: [PATCH 03/15] fix readme styling warnings --- README.md | 10 +++++----- README.source.md | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 22a65f31..617d03aa 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ The original repo has not been updated in two years and I needed some updates to Install the nuget package using following command: -```pws +```powershell Install-Package RazorLight -Version 3.0.0 ``` @@ -102,7 +102,7 @@ For embedded resource, the key is the namespace of the project where the templat The following examples are using this project structure: -``` +```text Project/ Model.cs Program.cs @@ -163,7 +163,7 @@ int templateKey = 322; string result = await engine.CompileRenderAsync(templateKey.ToString(), new { Name = "John Doe" }); ``` -You can find a full sample [here](https://github.com/toddams/RazorLight/tree/master/samples/RazorLight.Samples) +You can find more at the [RazorLight.Samples](samples/RazorLight.Samples). # Includes (aka Partial views) @@ -286,11 +286,11 @@ var metadataReference = MetadataReference.CreateFromFile("path-to-your-assembly" ### I'm getting errors after upgrading to ASP.NET Core 3.0 when using runtime compilation -Please see: https://docs.microsoft.com/en-us/aspnet/core/razor-pages/sdk?view=aspnetcore-3.1#use-the-razor-sdk +Please see [the warning in the Microsoft documentation](https://learn.microsoft.com/en-us/aspnet/core/razor-pages/sdk?view=aspnetcore-3.1#properties-1): > Starting with ASP.NET Core 3.0, MVC Views or Razor Pages aren't served by default if the `RazorCompileOnBuild` or `RazorCompileOnPublish` MSBuild properties in the project file are disabled. Applications must add an explicit reference to the `Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation` package if the app relies on runtime compilation to process .cshtml files. -### I'm getting a Null Reference Exception after upgrading to RazorLight-2.0.0-beta2 or later. +### I'm getting a Null Reference Exception after upgrading to RazorLight-2.0.0-beta2 or later The most common scenario is that some people were using RazorLight's ability to render raw strings as templates. While this is still somewhat supported (you can't use advanced features like partial views), what is not supported (right now) is using the caching provider with raw strings. A workaround is to use a dummy class. diff --git a/README.source.md b/README.source.md index 1aef9a81..ddedb4dc 100644 --- a/README.source.md +++ b/README.source.md @@ -27,7 +27,7 @@ The original repo has not been updated in two years and I needed some updates to Install the nuget package using following command: -```pws +```powershell Install-Package RazorLight -Version 3.0.0 ``` @@ -55,7 +55,7 @@ For embedded resource, the key is the namespace of the project where the templat The following examples are using this project structure: -``` +```text Project/ Model.cs Program.cs @@ -92,7 +92,7 @@ int templateKey = 322; string result = await engine.CompileRenderAsync(templateKey.ToString(), new { Name = "John Doe" }); ``` -You can find a full sample [here](https://github.com/toddams/RazorLight/tree/master/samples/RazorLight.Samples) +You can find more at the [RazorLight.Samples](samples/RazorLight.Samples). # Includes (aka Partial views) @@ -215,11 +215,11 @@ var metadataReference = MetadataReference.CreateFromFile("path-to-your-assembly" ### I'm getting errors after upgrading to ASP.NET Core 3.0 when using runtime compilation -Please see: https://docs.microsoft.com/en-us/aspnet/core/razor-pages/sdk?view=aspnetcore-3.1#use-the-razor-sdk +Please see [the warning in the Microsoft documentation](https://learn.microsoft.com/en-us/aspnet/core/razor-pages/sdk?view=aspnetcore-3.1#properties-1): > Starting with ASP.NET Core 3.0, MVC Views or Razor Pages aren't served by default if the `RazorCompileOnBuild` or `RazorCompileOnPublish` MSBuild properties in the project file are disabled. Applications must add an explicit reference to the `Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation` package if the app relies on runtime compilation to process .cshtml files. -### I'm getting a Null Reference Exception after upgrading to RazorLight-2.0.0-beta2 or later. +### I'm getting a Null Reference Exception after upgrading to RazorLight-2.0.0-beta2 or later The most common scenario is that some people were using RazorLight's ability to render raw strings as templates. While this is still somewhat supported (you can't use advanced features like partial views), what is not supported (right now) is using the caching provider with raw strings. A workaround is to use a dummy class. From 576b9985547ab178dbd2b94e7e5239b5bfbda6b4 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:19:37 +0100 Subject: [PATCH 04/15] one way of using csharp styling --- README.md | 4 ++-- README.source.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 617d03aa..bcfe38a8 100644 --- a/README.md +++ b/README.md @@ -238,7 +238,7 @@ The short answer is, you have to set a project to use the memory caching provide :x: You used to be able to write: -```c# +```CSharp var razorEngine = new RazorLightEngineBuilder() .UseMemoryCachingProvider() .Build(); @@ -248,7 +248,7 @@ var razorEngine = new RazorLightEngineBuilder() :heavy_check_mark: -```c# +```CSharp var razorEngine = new RazorLightEngineBuilder() .UseEmbeddedResourcesProject(typeof(AnyTypeInYourSolution)) // exception without this (or another project type) .UseMemoryCachingProvider() diff --git a/README.source.md b/README.source.md index ddedb4dc..8bbdc170 100644 --- a/README.source.md +++ b/README.source.md @@ -167,7 +167,7 @@ The short answer is, you have to set a project to use the memory caching provide :x: You used to be able to write: -```c# +```CSharp var razorEngine = new RazorLightEngineBuilder() .UseMemoryCachingProvider() .Build(); @@ -177,7 +177,7 @@ var razorEngine = new RazorLightEngineBuilder() :heavy_check_mark: -```c# +```CSharp var razorEngine = new RazorLightEngineBuilder() .UseEmbeddedResourcesProject(typeof(AnyTypeInYourSolution)) // exception without this (or another project type) .UseMemoryCachingProvider() From ae4d46b971dc60a72625853c231d4b86bb1224a2 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:26:35 +0100 Subject: [PATCH 05/15] cshtml --- README.source.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.source.md b/README.source.md index 8bbdc170..9f0bc8d5 100644 --- a/README.source.md +++ b/README.source.md @@ -98,7 +98,7 @@ You can find more at the [RazorLight.Samples](samples/RazorLight.Samples). Include feature is useful when you have reusable parts of your templates you want to share between different views. Includes are an effective way of breaking up large templates into smaller components. They can reduce duplication of template content and allow elements to be reused. _This feature requires you to use the RazorLight Project system, otherwise there is no way to locate the partial._ -```CSharp +```cshtml @model MyProject.TestViewModel
Hello @Model.Title @@ -131,7 +131,7 @@ Console.WriteLine(result); // Output: & In order to disable encoding for the entire document - just set `"DisableEncoding"` variable to true -```html +```cshtml @model TestViewModel @{ DisableEncoding = true; } @@ -143,7 +143,7 @@ In order to disable encoding for the entire document - just set `"DisableEncodin Visual Studio tooling knows nothing about RazorLight and assumes, that the view you are using - is a typical ASP.NET MVC template. In order to enable Intellisense for RazorLight templates, you should give Visual Studio a little hint about the base template class, that all your templates inherit implicitly -```CSharp +```cshtml @using RazorLight @inherits TemplatePage @@ -205,12 +205,12 @@ Most problems with RazorLight deal with deploying it on a new machine, in a dock When RazorLight compiles your template - it loads all the assemblies from your entry assembly and creates MetadataReference from it. This is a default strategy and it works in 99% of the time. But sometimes compilation crashes with an exception message like "Can not find assembly My.Super.Assembly2000". In order to solve this problem you can pass additional metadata references to RazorLight. ```CSharp -var metadataReference = MetadataReference.CreateFromFile("path-to-your-assembly") +var metadataReference = MetadataReference.CreateFromFile("path-to-your-assembly"); - var engine = new RazorLightEngineBuilder() - .UseMemoryCachingProvider() - .AddMetadataReferences(metadataReference) - .Build(); +var engine = new RazorLightEngineBuilder() + .UseMemoryCachingProvider() + .AddMetadataReferences(metadataReference) + .Build(); ``` ### I'm getting errors after upgrading to ASP.NET Core 3.0 when using runtime compilation From 5d66e4352487962bcfabe13c2f7f4856f9581f3a Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:26:52 +0100 Subject: [PATCH 06/15] cshtml --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bcfe38a8..19806958 100644 --- a/README.md +++ b/README.md @@ -169,7 +169,7 @@ You can find more at the [RazorLight.Samples](samples/RazorLight.Samples). Include feature is useful when you have reusable parts of your templates you want to share between different views. Includes are an effective way of breaking up large templates into smaller components. They can reduce duplication of template content and allow elements to be reused. _This feature requires you to use the RazorLight Project system, otherwise there is no way to locate the partial._ -```CSharp +```cshtml @model MyProject.TestViewModel
Hello @Model.Title @@ -202,7 +202,7 @@ Console.WriteLine(result); // Output: & In order to disable encoding for the entire document - just set `"DisableEncoding"` variable to true -```html +```cshtml @model TestViewModel @{ DisableEncoding = true; } @@ -214,7 +214,7 @@ In order to disable encoding for the entire document - just set `"DisableEncodin Visual Studio tooling knows nothing about RazorLight and assumes, that the view you are using - is a typical ASP.NET MVC template. In order to enable Intellisense for RazorLight templates, you should give Visual Studio a little hint about the base template class, that all your templates inherit implicitly -```CSharp +```cshtml @using RazorLight @inherits TemplatePage @@ -276,12 +276,12 @@ Most problems with RazorLight deal with deploying it on a new machine, in a dock When RazorLight compiles your template - it loads all the assemblies from your entry assembly and creates MetadataReference from it. This is a default strategy and it works in 99% of the time. But sometimes compilation crashes with an exception message like "Can not find assembly My.Super.Assembly2000". In order to solve this problem you can pass additional metadata references to RazorLight. ```CSharp -var metadataReference = MetadataReference.CreateFromFile("path-to-your-assembly") +var metadataReference = MetadataReference.CreateFromFile("path-to-your-assembly"); - var engine = new RazorLightEngineBuilder() - .UseMemoryCachingProvider() - .AddMetadataReferences(metadataReference) - .Build(); +var engine = new RazorLightEngineBuilder() + .UseMemoryCachingProvider() + .AddMetadataReferences(metadataReference) + .Build(); ``` ### I'm getting errors after upgrading to ASP.NET Core 3.0 when using runtime compilation From 370696d1dabc37d145a1bdf594916875d1630419 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:32:01 +0100 Subject: [PATCH 07/15] lowercase xml highlighting --- README.md | 6 +++--- README.source.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 19806958..e88b1621 100644 --- a/README.md +++ b/README.md @@ -299,7 +299,7 @@ The most common scenario is that some people were using RazorLight's ability to Add these property groups to your **entry point csproj**. It has to be the entry point project. For example: ASP.NET Core web project, .NET Core Console project, etc. -```XML +```xml true @@ -312,7 +312,7 @@ It has to be the entry point project. For example: ASP.NET Core web project, .NE Set PreserveCompilationContext to true in your \*.csproj file's PropertyGroup tag. -```XML +```xml ... true @@ -326,7 +326,7 @@ Additionally, RazorLight allows you to specifically locate any `MetadataReferenc By default, the 3.0 SDK avoids copying references to the build output. Set `PreserveCompilationReferences` and `PreserveCompilationContext` to true in your \*.csproj file's PropertyGroup tag. -```XML +```xml true true diff --git a/README.source.md b/README.source.md index 9f0bc8d5..f73dcfe9 100644 --- a/README.source.md +++ b/README.source.md @@ -228,7 +228,7 @@ The most common scenario is that some people were using RazorLight's ability to Add these property groups to your **entry point csproj**. It has to be the entry point project. For example: ASP.NET Core web project, .NET Core Console project, etc. -```XML +```xml true @@ -241,7 +241,7 @@ It has to be the entry point project. For example: ASP.NET Core web project, .NE Set PreserveCompilationContext to true in your \*.csproj file's PropertyGroup tag. -```XML +```xml ... true @@ -255,7 +255,7 @@ Additionally, RazorLight allows you to specifically locate any `MetadataReferenc By default, the 3.0 SDK avoids copying references to the build output. Set `PreserveCompilationReferences` and `PreserveCompilationContext` to true in your \*.csproj file's PropertyGroup tag. -```XML +```xml true true From dcf932046ead5714a75f144de881ad8c75677fb6 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:35:31 +0100 Subject: [PATCH 08/15] fix link --- README.md | 2 +- README.source.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e88b1621..fe276bd0 100644 --- a/README.md +++ b/README.md @@ -288,7 +288,7 @@ var engine = new RazorLightEngineBuilder() Please see [the warning in the Microsoft documentation](https://learn.microsoft.com/en-us/aspnet/core/razor-pages/sdk?view=aspnetcore-3.1#properties-1): -> Starting with ASP.NET Core 3.0, MVC Views or Razor Pages aren't served by default if the `RazorCompileOnBuild` or `RazorCompileOnPublish` MSBuild properties in the project file are disabled. Applications must add an explicit reference to the `Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation` package if the app relies on runtime compilation to process .cshtml files. +> Starting with ASP.NET Core 3.0, MVC Views or Razor Pages aren't served by default if the `RazorCompileOnBuild` or `RazorCompileOnPublish` MSBuild properties in the project file are disabled. Applications must add an explicit reference to the [Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation](https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation) package if the app relies on runtime compilation to process `.cshtml` files. ### I'm getting a Null Reference Exception after upgrading to RazorLight-2.0.0-beta2 or later diff --git a/README.source.md b/README.source.md index f73dcfe9..838f1384 100644 --- a/README.source.md +++ b/README.source.md @@ -217,7 +217,7 @@ var engine = new RazorLightEngineBuilder() Please see [the warning in the Microsoft documentation](https://learn.microsoft.com/en-us/aspnet/core/razor-pages/sdk?view=aspnetcore-3.1#properties-1): -> Starting with ASP.NET Core 3.0, MVC Views or Razor Pages aren't served by default if the `RazorCompileOnBuild` or `RazorCompileOnPublish` MSBuild properties in the project file are disabled. Applications must add an explicit reference to the `Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation` package if the app relies on runtime compilation to process .cshtml files. +> Starting with ASP.NET Core 3.0, MVC Views or Razor Pages aren't served by default if the `RazorCompileOnBuild` or `RazorCompileOnPublish` MSBuild properties in the project file are disabled. Applications must add an explicit reference to the [Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation](https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation) package if the app relies on runtime compilation to process `.cshtml` files. ### I'm getting a Null Reference Exception after upgrading to RazorLight-2.0.0-beta2 or later From b9ef46723085933fde88c94a906d5b814a8aae1c Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:38:35 +0100 Subject: [PATCH 09/15] fix indent --- README.md | 20 ++++++++++---------- README.source.md | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index fe276bd0..a1cb180a 100644 --- a/README.md +++ b/README.md @@ -300,12 +300,12 @@ Add these property groups to your **entry point csproj**. It has to be the entry point project. For example: ASP.NET Core web project, .NET Core Console project, etc. ```xml - - - true - false - false - + + + true + false + false + ``` ### I'm getting "Can't load metadata reference from the entry assembly" exception @@ -314,8 +314,8 @@ Set PreserveCompilationContext to true in your \*.csproj file's PropertyGroup ta ```xml - ... - true + ... + true ``` @@ -328,8 +328,8 @@ Set `PreserveCompilationReferences` and `PreserveCompilationContext` to true in ```xml - true - true + true + true ``` diff --git a/README.source.md b/README.source.md index 838f1384..22cfdd9d 100644 --- a/README.source.md +++ b/README.source.md @@ -229,12 +229,12 @@ Add these property groups to your **entry point csproj**. It has to be the entry point project. For example: ASP.NET Core web project, .NET Core Console project, etc. ```xml - - - true - false - false - + + + true + false + false + ``` ### I'm getting "Can't load metadata reference from the entry assembly" exception @@ -243,8 +243,8 @@ Set PreserveCompilationContext to true in your \*.csproj file's PropertyGroup ta ```xml - ... - true + ... + true ``` @@ -257,8 +257,8 @@ Set `PreserveCompilationReferences` and `PreserveCompilationContext` to true in ```xml - true - true + true + true ``` From 407d4109d66c5b81b1a323d7806499ff22379b02 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:40:34 +0100 Subject: [PATCH 10/15] fix c# indent for readability --- README.source.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.source.md b/README.source.md index 22cfdd9d..3e7de851 100644 --- a/README.source.md +++ b/README.source.md @@ -80,9 +80,9 @@ If you store your templates in database - it is recommended to create custom Raz ```CSharp var project = new EntityFrameworkRazorProject(new AppDbContext()); var engine = new RazorLightEngineBuilder() - .UseProject(project) - .UseMemoryCachingProvider() - .Build(); + .UseProject(project) + .UseMemoryCachingProvider() + .Build(); // For key as a GUID string result = await engine.CompileRenderAsync("6cc277d5-253e-48e0-8a9a-8fe3cae17e5b", new { Name = "John Doe" }); @@ -169,8 +169,8 @@ You used to be able to write: ```CSharp var razorEngine = new RazorLightEngineBuilder() -.UseMemoryCachingProvider() -.Build(); + .UseMemoryCachingProvider() + .Build(); ``` ... but this now throws an exception, saying, "`_razorLightProject cannot be null`". @@ -179,9 +179,9 @@ var razorEngine = new RazorLightEngineBuilder() ```CSharp var razorEngine = new RazorLightEngineBuilder() - .UseEmbeddedResourcesProject(typeof(AnyTypeInYourSolution)) // exception without this (or another project type) - .UseMemoryCachingProvider() - .Build(); + .UseEmbeddedResourcesProject(typeof(AnyTypeInYourSolution)) // exception without this (or another project type) + .UseMemoryCachingProvider() + .Build(); ``` Affects: RazorLight-2.0.0-beta1 and later. @@ -208,9 +208,9 @@ When RazorLight compiles your template - it loads all the assemblies from your e var metadataReference = MetadataReference.CreateFromFile("path-to-your-assembly"); var engine = new RazorLightEngineBuilder() - .UseMemoryCachingProvider() - .AddMetadataReferences(metadataReference) - .Build(); + .UseMemoryCachingProvider() + .AddMetadataReferences(metadataReference) + .Build(); ``` ### I'm getting errors after upgrading to ASP.NET Core 3.0 when using runtime compilation From bd75cc5c39646fa11815658dc14fe73d659216fc Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:40:48 +0100 Subject: [PATCH 11/15] build md --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a1cb180a..6515607a 100644 --- a/README.md +++ b/README.md @@ -151,9 +151,9 @@ If you store your templates in database - it is recommended to create custom Raz ```CSharp var project = new EntityFrameworkRazorProject(new AppDbContext()); var engine = new RazorLightEngineBuilder() - .UseProject(project) - .UseMemoryCachingProvider() - .Build(); + .UseProject(project) + .UseMemoryCachingProvider() + .Build(); // For key as a GUID string result = await engine.CompileRenderAsync("6cc277d5-253e-48e0-8a9a-8fe3cae17e5b", new { Name = "John Doe" }); @@ -240,8 +240,8 @@ You used to be able to write: ```CSharp var razorEngine = new RazorLightEngineBuilder() -.UseMemoryCachingProvider() -.Build(); + .UseMemoryCachingProvider() + .Build(); ``` ... but this now throws an exception, saying, "`_razorLightProject cannot be null`". @@ -250,9 +250,9 @@ var razorEngine = new RazorLightEngineBuilder() ```CSharp var razorEngine = new RazorLightEngineBuilder() - .UseEmbeddedResourcesProject(typeof(AnyTypeInYourSolution)) // exception without this (or another project type) - .UseMemoryCachingProvider() - .Build(); + .UseEmbeddedResourcesProject(typeof(AnyTypeInYourSolution)) // exception without this (or another project type) + .UseMemoryCachingProvider() + .Build(); ``` Affects: RazorLight-2.0.0-beta1 and later. @@ -279,9 +279,9 @@ When RazorLight compiles your template - it loads all the assemblies from your e var metadataReference = MetadataReference.CreateFromFile("path-to-your-assembly"); var engine = new RazorLightEngineBuilder() - .UseMemoryCachingProvider() - .AddMetadataReferences(metadataReference) - .Build(); + .UseMemoryCachingProvider() + .AddMetadataReferences(metadataReference) + .Build(); ``` ### I'm getting errors after upgrading to ASP.NET Core 3.0 when using runtime compilation From 8fd737dcd78228dfd655c88e60cae2d562e95352 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:43:19 +0100 Subject: [PATCH 12/15] streamline cshtml formatting --- README.md | 5 +++-- README.source.md | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6515607a..8f4db573 100644 --- a/README.md +++ b/README.md @@ -171,8 +171,9 @@ Include feature is useful when you have reusable parts of your templates you wan ```cshtml @model MyProject.TestViewModel +
- Hello @Model.Title + Hello @Model.Title
@{ await IncludeAsync("SomeView.cshtml", Model); } @@ -219,7 +220,7 @@ Visual Studio tooling knows nothing about RazorLight and assumes, that the view @inherits TemplatePage - Your awesome template goes here, @Model.Name + Your awesome template goes here, @Model.Name ``` diff --git a/README.source.md b/README.source.md index 3e7de851..9d68486b 100644 --- a/README.source.md +++ b/README.source.md @@ -100,8 +100,9 @@ Include feature is useful when you have reusable parts of your templates you wan ```cshtml @model MyProject.TestViewModel +
- Hello @Model.Title + Hello @Model.Title
@{ await IncludeAsync("SomeView.cshtml", Model); } @@ -148,7 +149,7 @@ Visual Studio tooling knows nothing about RazorLight and assumes, that the view @inherits TemplatePage - Your awesome template goes here, @Model.Name + Your awesome template goes here, @Model.Name ``` From 9371a51cf2176a906a3a25c3e41c375252ccf2dd Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:50:28 +0100 Subject: [PATCH 13/15] NuGet casing --- README.source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.source.md b/README.source.md index 9d68486b..0e393801 100644 --- a/README.source.md +++ b/README.source.md @@ -25,7 +25,7 @@ The original repo has not been updated in two years and I needed some updates to # Quickstart -Install the nuget package using following command: +Install the NuGet package using following command: ```powershell Install-Package RazorLight -Version 3.0.0 From a90db293c07d706338b38db83d186f3464084740 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:51:04 +0100 Subject: [PATCH 14/15] compile --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f4db573..d0357477 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ The original repo has not been updated in two years and I needed some updates to # Quickstart -Install the nuget package using following command: +Install the NuGet package using following command: ```powershell Install-Package RazorLight -Version 3.0.0 From 569a9199199863f22892572f3075abaf25ec6da9 Mon Sep 17 00:00:00 2001 From: Erwin Kramer Date: Sat, 3 Jan 2026 00:53:16 +0100 Subject: [PATCH 15/15] language --- README.md | 4 ++-- README.source.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d0357477..46af1364 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,9 @@ To change this file edit the source file and then run MarkdownSnippets. # RazorLight -Use Razor to build templates from Files / EmbeddedResources / Strings / Database or your custom source outside of ASP.NET MVC. No redundant dependencies and workarounds in pair with excellent performance and **.NET 8.0, NET 9.0 and .NET 10.0** support. +Use Razor to build templates from Files / EmbeddedResources / Strings / Database or your custom source outside of ASP.NET MVC. No redundant dependencies and workarounds in pair with excellent performance and **.NET 8.0, 9.0 and 10.0** support. -Forked from original by [@toddams](https://github.com/toddams/RazorLight/) +Forked from original by [@toddams](https://github.com/toddams/RazorLight/). My packages are the same names, but prefixed with `jcamp.` to differentiate them. diff --git a/README.source.md b/README.source.md index 0e393801..27f5c636 100644 --- a/README.source.md +++ b/README.source.md @@ -2,9 +2,9 @@ # RazorLight -Use Razor to build templates from Files / EmbeddedResources / Strings / Database or your custom source outside of ASP.NET MVC. No redundant dependencies and workarounds in pair with excellent performance and **.NET 8.0, NET 9.0 and .NET 10.0** support. +Use Razor to build templates from Files / EmbeddedResources / Strings / Database or your custom source outside of ASP.NET MVC. No redundant dependencies and workarounds in pair with excellent performance and **.NET 8.0, 9.0 and 10.0** support. -Forked from original by [@toddams](https://github.com/toddams/RazorLight/) +Forked from original by [@toddams](https://github.com/toddams/RazorLight/). My packages are the same names, but prefixed with `jcamp.` to differentiate them.