Skip to content

Releases: Matheis1992/RazorEngine

RazorEngine.NetFramework 5.0.1

Choose a tag to compare

@github-actions github-actions released this 31 Oct 23:42
2dec217
  • (FIX) A template is compiled only once when several threads miss the cache for it at the same time (RunCompile, and layouts and @Include while a template runs). Before, every thread compiled it: in a test, 8 threads starting together compiled the same template 8 times. Each of these compiles cost the full compile time and loaded another assembly that stays in memory until its AppDomain is unloaded, typically when a web application starts and many requests need the same templates. The other threads now wait for the first compile and use its result, or get its exception if it fails (the next call then compiles again); different templates and different model types still compile in parallel. See Caching.
  • (FIX) new DefaultCachingProvider(), the caching provider of every new TemplateServiceConfiguration, created a second internal cache that was never disposed. Its AppDomain.AssemblyResolve handler stayed registered and kept its objects alive for the life of the process, one per configuration, also after disposing the service.
  • (PERFORMANCE) The default reference resolver (UseCurrentAssembliesReferenceResolver) checks each loaded assembly once instead of on every compile. Checking whether an assembly's file exists took about 60 µs per assembly; with 223 loaded assemblies that was about 16 ms per compile and is now below 0.1 ms after the first compile. The references passed to the compiler are the same.
  • (PERFORMANCE) Anonymous models with lists of anonymous objects (for example new { Items = list.Select(x => new { x.Name, x.Price }) }) render about 4 times faster. For each list item, the dynamic wrapper of such models first tried the DLR, which cannot bind the enumerator of a list of anonymous types, and only then fell back to reflection: three caught exceptions per item. It now remembers, per type, which members without arguments only work with reflection and calls them directly. In a benchmark with 1000 rows, a run took about 4.5 ms instead of 22 ms, with no exceptions instead of about 3000. The results are the same; missing members still fail as before, and members of dynamic objects such as ExpandoObject (which depend on the instance) are resolved as before.
  • (FIX) A null argument in a call on an anonymous model (for example @Model.Formatter.Describe(null)) is passed on. Before, the dynamic wrapper failed with a NullReferenceException before it bound the call.
  • (BUILD) Package validation compares both packages with 5.0.0 (also the Roslyn package now), so the 5.0.x releases are checked to be compatible with 5.0.0. The 5.0.0 entries in CompatibilitySuppressions.xml are removed with it.

NuGet: https://www.nuget.org/packages/RazorEngine.NetFramework/5.0.1
NuGet (Roslyn): https://www.nuget.org/packages/RazorEngine.NetFramework.Roslyn/5.0.1

RazorEngine.NetFramework 5.0.0

Choose a tag to compare

@github-actions github-actions released this 31 Oct 22:28
2c176b6

5.0.0 splits RazorEngine into two packages (#22): the core package no longer depends on Roslyn, and Roslyn becomes opt-in. Read Upgrading to 5.0 before updating.

Package Contents Dependencies
RazorEngine.NetFramework Razor integration, templating, caching, CodeDom compiler service Microsoft.AspNet.Razor 3.3.0
RazorEngine.NetFramework.Roslyn (new) RoslynCompilerServiceFactory, CSharpRoslynCompilerService, RoslynCompilerServiceBase, the metadata reference cache, LanguageVersion RazorEngine.NetFramework, Microsoft.CodeAnalysis.CSharp 5.6.0

Breaking changes

  • (BREAKING) CodeDom is the default compiler again. DefaultCompilerServiceFactory (the default CompilerServiceFactory) compiles templates with CodeDom (the csc.exe of .NET Framework, C# 5), as before 4.1. Templates that use C# 6 or newer syntax fail to compile unless you install the Roslyn package and set RoslynCompilerServiceFactory. Installing the Roslyn package alone does not change the compiler; it is an explicit opt-in.
  • (BREAKING) Roslyn moved to RazorEngine.NetFramework.Roslyn (assembly RazorEngine.NetFramework.Roslyn.dll, same signing key). The namespaces stay (RazorEngine.Roslyn, RazorEngine.Roslyn.CSharp); only the assembly part of assembly-qualified names changes, for example compilerServiceFactoryType="RazorEngine.Roslyn.RoslynCompilerServiceFactory, RazorEngine.NetFramework.Roslyn".
  • (BREAKING) DefaultCompilerServiceFactory.LanguageVersion removed. Use RoslynCompilerServiceFactory.LanguageVersion. RoslynCompilerServiceFactory no longer derives from DefaultCompilerServiceFactory; it implements ICompilerServiceFactory directly.
  • (BREAKING) Templates compiled with CodeDom are C# 5 again: code that relied on field as the C# 14 backing field changes meaning back (see the 4.1.0 notes).
  • (BREAKING) Removed the types that are obsolete since 4.3.0: CompilerServiceBuilder (RazorEngine never used it; set CompilerServiceFactory on the TemplateServiceConfiguration) and HtmlTemplateBase<T> (use TemplateBase<T>).
  • (BREAKING) Removed the members that are obsolete since 3.x:
    • TemplateBase.RazorEngine and ITemplate.RazorEngine: use Razor. Templates can now use the RazorEngine namespace without it being hidden by this property.
    • DynamicViewBag.AddDictionaryValues, AddDictionaryValuesEx and AddListValues: use AddDictionary or AddValue.
  • (BREAKING) As announced in 4.3.0, the implementation details IsolatedRazorEngineService.SanboxHelper, CrossAppDomainCleanUp.CleanupHelper and CleanupHelper.SubscribeHelper are internal. They were hidden from IntelliSense since 4.3.0 and only meant for RazorEngine's own AppDomain communication.

New

  • (NEW) The Roslyn package depends on exactly the same version of the core package ([5.0.0]), because both are released together and the Roslyn compiler service builds on the core's compiler base classes.
  • (NEW) Modern C# with CodeDom, without Roslyn in your process. CodeDomCompilerServiceFactory (and DefaultCompilerServiceFactory, which now derives from it) has CodeDomProviderFactory to compile with another CodeDomProvider, for example Microsoft.CodeDom.Providers.DotNetCompilerPlatform, and CompilerOptions for additional compiler switches such as /langversion:7.3 (with a provider that supports it). CSharpDirectCompilerService has a constructor that takes the CodeDomProvider; the compiler service disposes it. DirectCompilerServiceBase has CompilerOptions and a ConfigureCompilerParameters hook, and a factory derived from CodeDomCompilerServiceFactory can create its own service by overriding CreateCSharpCompilerService. See Roslyn.
  • (PACKAGING) The core package depends only on Microsoft.AspNet.Razor 3.3.0, so applications without the Roslyn package need no binding redirects for Roslyn's System.* dependencies, and ASP.NET no longer loads Roslyn from bin at startup.
  • (BUILD) Both packages are built, tested and released together with the same version. Package validation of the core package against 4.3.0 lists the intended breaking changes in CompatibilitySuppressions.xml.
  • (BUILD) The core tests no longer use Roslyn, which also shows that the core works without it. The tests that compare CodeDom and Roslyn moved to the Roslyn tests.
  • (FIX) Null arguments are rejected right away with an ArgumentNullException, for example in FluentTemplateServiceConfiguration, ActivateUsing and TypeLoader. The checks were Code Contracts calls (Contract.Requires), which the compiler removes unless CONTRACTS_FULL is defined, so they never ran and a null failed later with a less clear error.
  • (BUILD) Removed leftovers of tools the build does not use: the FxCop suppressions (SuppressMessage, including GlobalSuppressions.cs) and the Code Contracts [Pure] attributes. They had no effect.

NuGet: https://www.nuget.org/packages/RazorEngine.NetFramework/5.0.0
NuGet (Roslyn): https://www.nuget.org/packages/RazorEngine.NetFramework.Roslyn/5.0.0

RazorEngine.NetFramework 5.0.0-rc.1

Pre-release

Choose a tag to compare

@github-actions github-actions released this 29 Oct 23:59
c1eb200

Release candidate of 5.0.0: install it with prereleases enabled (Install-Package RazorEngine.NetFramework -Prerelease) and report problems in the issues before the final 5.0.0.

5.0.0 splits RazorEngine into two packages (#22): the core package no longer depends on Roslyn, and Roslyn becomes opt-in. Read Upgrading to 5.0 before updating.

Package Contents Dependencies
RazorEngine.NetFramework Razor integration, templating, caching, CodeDom compiler service Microsoft.AspNet.Razor 3.3.0
RazorEngine.NetFramework.Roslyn (new) RoslynCompilerServiceFactory, CSharpRoslynCompilerService, RoslynCompilerServiceBase, the metadata reference cache, LanguageVersion RazorEngine.NetFramework, Microsoft.CodeAnalysis.CSharp 5.6.0

Breaking changes

  • (BREAKING) CodeDom is the default compiler again. DefaultCompilerServiceFactory (the default CompilerServiceFactory) compiles templates with CodeDom (the csc.exe of .NET Framework, C# 5), as before 4.1. Templates that use C# 6 or newer syntax fail to compile unless you install the Roslyn package and set RoslynCompilerServiceFactory. Installing the Roslyn package alone does not change the compiler; it is an explicit opt-in.
  • (BREAKING) Roslyn moved to RazorEngine.NetFramework.Roslyn (assembly RazorEngine.NetFramework.Roslyn.dll, same signing key). The namespaces stay (RazorEngine.Roslyn, RazorEngine.Roslyn.CSharp); only the assembly part of assembly-qualified names changes, for example compilerServiceFactoryType="RazorEngine.Roslyn.RoslynCompilerServiceFactory, RazorEngine.NetFramework.Roslyn".
  • (BREAKING) DefaultCompilerServiceFactory.LanguageVersion removed. Use RoslynCompilerServiceFactory.LanguageVersion. RoslynCompilerServiceFactory no longer derives from DefaultCompilerServiceFactory; it implements ICompilerServiceFactory directly.
  • (BREAKING) Templates compiled with CodeDom are C# 5 again: code that relied on field as the C# 14 backing field changes meaning back (see the 4.1.0 notes).
  • (BREAKING) Removed the types that are obsolete since 4.3.0: CompilerServiceBuilder (RazorEngine never used it; set CompilerServiceFactory on the TemplateServiceConfiguration) and HtmlTemplateBase<T> (use TemplateBase<T>).
  • (BREAKING) Removed the members that are obsolete since 3.x:
    • TemplateBase.RazorEngine and ITemplate.RazorEngine: use Razor. Templates can now use the RazorEngine namespace without it being hidden by this property.
    • DynamicViewBag.AddDictionaryValues, AddDictionaryValuesEx and AddListValues: use AddDictionary or AddValue.
  • (BREAKING) As announced in 4.3.0, the implementation details IsolatedRazorEngineService.SanboxHelper, CrossAppDomainCleanUp.CleanupHelper and CleanupHelper.SubscribeHelper are internal. They were hidden from IntelliSense since 4.3.0 and only meant for RazorEngine's own AppDomain communication.

New

  • (NEW) The Roslyn package depends on exactly the same version of the core package ([5.0.0]), because both are released together and the Roslyn compiler service builds on the core's compiler base classes.
  • (NEW) Modern C# with CodeDom, without Roslyn in your process. CodeDomCompilerServiceFactory (and DefaultCompilerServiceFactory, which now derives from it) has CodeDomProviderFactory to compile with another CodeDomProvider, for example Microsoft.CodeDom.Providers.DotNetCompilerPlatform, and CompilerOptions for additional compiler switches such as /langversion:7.3 (with a provider that supports it). CSharpDirectCompilerService has a constructor that takes the CodeDomProvider; the compiler service disposes it. DirectCompilerServiceBase has CompilerOptions and a ConfigureCompilerParameters hook, and a factory derived from CodeDomCompilerServiceFactory can create its own service by overriding CreateCSharpCompilerService. See Roslyn.
  • (PACKAGING) The core package depends only on Microsoft.AspNet.Razor 3.3.0, so applications without the Roslyn package need no binding redirects for Roslyn's System.* dependencies, and ASP.NET no longer loads Roslyn from bin at startup.
  • (BUILD) Both packages are built, tested and released together with the same version. Package validation of the core package against 4.3.0 lists the intended breaking changes in CompatibilitySuppressions.xml.
  • (BUILD) The core tests no longer use Roslyn, which also shows that the core works without it. The tests that compare CodeDom and Roslyn moved to the Roslyn tests.
  • (FIX) Null arguments are rejected right away with an ArgumentNullException, for example in FluentTemplateServiceConfiguration, ActivateUsing and TypeLoader. The checks were Code Contracts calls (Contract.Requires), which the compiler removes unless CONTRACTS_FULL is defined, so they never ran and a null failed later with a less clear error.
  • (BUILD) Removed leftovers of tools the build does not use: the FxCop suppressions (SuppressMessage, including GlobalSuppressions.cs) and the Code Contracts [Pure] attributes. They had no effect.

NuGet: https://www.nuget.org/packages/RazorEngine.NetFramework/5.0.0-rc.1
NuGet (Roslyn): https://www.nuget.org/packages/RazorEngine.NetFramework.Roslyn/5.0.0-rc.1

RazorEngine.NetFramework 4.3.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 17:26
8177a0a

No breaking changes; package validation against 4.2.0 checks that in CI. Code that uses one of the newly obsolete types gets a compiler warning (CS0618), which fails the build if warnings are treated as errors.

  • (OBSOLETE) Public types without a real use are marked [Obsolete] and will be removed in 5.0:
    • CompilerServiceBuilder: RazorEngine never used it, so setting its factory had no effect. Set CompilerServiceFactory on the TemplateServiceConfiguration.
    • HtmlTemplateBase<T>: adds nothing to TemplateBase<T>; use TemplateBase<T>.
  • (DOCS) Use RoslynCompilerServiceFactory if your templates rely on Roslyn (modern C#, a pinned LanguageVersion). It does the same as DefaultCompilerServiceFactory today, but 5.0 is planned to compile with CodeDom by default again and move Roslyn into a separate package (#22); RoslynCompilerServiceFactory will keep selecting Roslyn. The examples in Roslyn use it.
  • Implementation details that are public by accident are hidden from IntelliSense ([EditorBrowsable(Never)]): IsolatedRazorEngineService.SanboxHelper (despite its name no sandbox), CrossAppDomainCleanUp.CleanupHelper and CleanupHelper.SubscribeHelper. They become internal in 5.0.
  • (BUILD) Removed dead code that was never compiled or never ran: code disabled with #if DISABLED (about 400 lines of the embedded Impromptu code, and the unused IRazorEngineCore interface), a regular expression in the Impromptu code that only that code used, the never-compiled Silverlight variants (#if SILVERLIGHT5), a commented-out method, and the Mono code paths in RazorEngine's own code (the fork targets .NET Framework 4.8 on Windows; the Mono checks inside the embedded Impromptu code stay as third-party code).
  • (BUILD) Removed the remaining unnecessary using directives (145).
  • (BUILD) Package validation baseline moved to 4.2.0.

NuGet: https://www.nuget.org/packages/RazorEngine.NetFramework/4.3.0

RazorEngine.NetFramework 4.2.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 01:34
fabc05e
  • (NEW) The C# language version of templates can be pinned with DefaultCompilerServiceFactory.LanguageVersion (also on RoslynCompilerServiceFactory, and CSharpRoslynCompilerService.LanguageVersion). The default stays the newest version the bundled Roslyn supports (C# 14). Pin an older version when a newer C# version changes the meaning of existing templates, see the field entry under 4.1.0:

    config.CompilerServiceFactory = new DefaultCompilerServiceFactory { LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp13 };
  • (PERFORMANCE) The Roslyn compiler service caches the metadata references of the loaded assemblies templates are compiled against, per AppDomain, so Roslyn reuses what it read from them instead of reading and analyzing every referenced assembly on each compile. Each compile after the first is about 35 to 50% faster: in a benchmark, about 25 ms instead of 40 ms with 64 loaded assemblies, and about 48 ms instead of 95 ms with 255. The first compile in a process is unchanged (about 2 s for loading Roslyn). A loaded assembly cannot change, so the cache never goes stale; references given as a file path, stream or byte array (by a custom IReferenceResolver) are read on every compile. Templates themselves are not cached by this; changed templates are recompiled as before.

  • (BUILD) dotnet pack validates the package against the last published version (package validation, baseline 4.1.0) and fails on breaking changes of the public API.

  • (DOCS) The README links the documentation pages in doc (with absolute links, so they also work on nuget.org) instead of the original project's website, and its AppDomain example for cleaning up temporary files uses a fully trusted AppDomain instead of suggesting a partially trusted one.

  • (DOCS) New page Caching: how compiled templates are cached (template key and model type), what RunCompile, Compile, Run and IsTemplateCached do, the three caching providers with examples for invalidating, why invalidating does not free memory (each recompile loads a new assembly that stays until its AppDomain is unloaded) and when temporary files are deleted.

  • (DOCS) Roslyn shows how to pin LanguageVersion when RazorEngine is configured in app.config/web.config: derive a factory that sets it in its constructor and name that type in compilerServiceFactoryType.

  • (DOCS) Outdated passages removed from the documentation: links to the original project's website, notes about Mono (the fork targets .NET Framework 4.8 on Windows) and an old Travis CI link. ReferenceResolver.md explains which compiler needs which references.

  • (BUILD) Removed files and projects that nothing used or shipped: RazorEngine.Mvc, RazorEngine.Hosts.Console, the old FSharp.Formatting doc site, the class diagram and an unused ruleset. The tests build TestHelper.dll instead of using a checked-in binary.

NuGet: https://www.nuget.org/packages/RazorEngine.NetFramework/4.2.0

RazorEngine.NetFramework 4.1.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 23:56
af46871

4.1.0 switches templates to a modern C# compiler and removes the APIs that were obsolete since 3.5, as well as VB.NET templates.
Unchanged: the template syntax (Razor 3, Microsoft.AspNet.Razor 3.3.0), the namespaces, the assembly name RazorEngine.NetFramework.dll and its signing key, and .NET Framework 4.8.
Read the breaking changes below before updating; doc/Upgrading.md has the migration steps.

Highlights

  • (NEW) Modern C# in templates. Roslyn (Microsoft.CodeAnalysis.CSharp) is updated from 1.3.2 to 5.6.0 and is now the default compiler. Templates can use C# up to C# 14 instead of C# 5: string interpolation, ?., nameof, tuples and deconstruction, pattern matching, switch expressions and more. For example:

    <p>@($"Hello {Model.Name}!")</p>
    <p>@(Model.Nickname?.ToUpper() ?? "no nickname")</p>
    @{ var text = Model.Age switch { >= 18 => "adult", _ => "child" }; }
    <p>@text</p>
  • (NEW) Fewer dependencies. The package now only depends on Microsoft.AspNet.Razor 3.3.0 and Microsoft.CodeAnalysis.CSharp 5.6.0. The pins of System.Collections.Immutable 1.3.1, System.Reflection.Metadata 1.4.2 and System.Security.Cryptography.X509Certificates 4.3.2, which only existed for the old Roslyn, are gone.

Breaking changes

  • (BREAKING) Roslyn is the default compiler. DefaultCompilerServiceFactory now compiles templates in-process with Roslyn instead of starting csc.exe through CodeDom.

    • Templates are still compiled optimized and with the RAZORENGINE preprocessor symbol, as with CodeDom, so #if RAZORENGINE keeps working.

    • The first compile in a process (or AppDomain) takes longer, because Roslyn is loaded and JIT-compiled there once: about 2 s instead of about 0.2 s with CodeDom. Later compiles do not start a separate csc.exe process and are faster (in a benchmark about 40 ms instead of about 85 ms; 4.2.0 brings this down to about 26 ms). From about 30 templates per process on, Roslyn is faster overall.

    • Roslyn runs inside the process: it needs about 55 MB more memory per process, and per AppDomain of IsolatedRazorEngineService.

    • Debugging: with Roslyn, Debug = true does not let you step into templates with the debugger.

    • To keep the old compiler (C# 5, csc.exe), for example for debugging, use the new CodeDomCompilerServiceFactory:

      config.CompilerServiceFactory = new RazorEngine.Compilation.CodeDomCompilerServiceFactory();

      or in the configuration file: <razorEngine compilerServiceFactoryType="RazorEngine.Compilation.CodeDomCompilerServiceFactory, RazorEngine.NetFramework">.

    • RoslynCompilerServiceFactory still exists and now does the same as DefaultCompilerServiceFactory.

  • (BREAKING) C# 14 can change the meaning of existing template code. Templates were compiled as C# 5 before and are compiled with the newest C# version now. Code that compiles with both usually behaves the same, with one known exception that does not cause a compile error:

    • Since C# 14, field inside a property accessor is the property's backing field. A template that declares its own member named field (for example in @functions) and returns it from a property accessor now gets the backing field instead (for example null).
    • Rename the member, or, from 4.2.0 on, pin LanguageVersion.CSharp13 (see 4.2.0), or keep the CodeDom compiler.
    • Roslyn lists all C# breaking changes in https://github.com/dotnet/roslyn/tree/main/docs/compilers/CSharp.
  • (BREAKING) Binding redirects for Roslyn's dependencies. Roslyn 5.6.0 brings newer System.* assemblies (System.Collections.Immutable 10, System.Reflection.Metadata 10, System.Memory and others). .NET Framework applications need binding redirects for them:

    • SDK-style projects generate them automatically (AutoGenerateBindingRedirects).

    • For packages.config projects, NuGet adds them to app.config/web.config on install. Check that existing, hand-written redirects for these assemblies point to the new versions.

    • A FileLoadException for one of these assemblies at the first template compile means a binding redirect is missing.

    • Custom AppDomains for IsolatedRazorEngineService need the application's configuration file, otherwise the redirects do not apply there. IsolatedRazorEngineService.Create() already does this; for your own domains set it yourself:

      var setup = new AppDomainSetup
      {
          ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
          ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
      };
      var service = IsolatedRazorEngineService.Create(() => AppDomain.CreateDomain("Templates", null, setup));
  • (BREAKING) Legacy API removed (obsolete since 3.5). Replacements:

    Removed Use instead
    Razor.Parse(template, model, name) Engine.Razor.RunCompile(template, name, null, model)
    Razor.Compile(template, modelType, name) Engine.Razor.Compile(template, name, modelType)
    Razor.Run(name, model) Engine.Razor.Run(name, null, model)
    TemplateService, ITemplateService RazorEngineService.Create(config), IRazorEngineService
    IsolatedTemplateService IsolatedRazorEngineService.Create(...)
    ITemplate.TemplateService, TemplateBase.TemplateService TemplateBase.Razor
    Parallel query plans (IParallelQueryPlan, ...) your own Parallel.ForEach/PLINQ around Run

    The RunCompile/Compile/Run overloads with a template string are extension methods in RazorEngine.Templating.

  • (BREAKING) Template resolvers removed (obsolete since 3.5). Template managers replace them:

    Removed Use instead
    ITemplateResolver, DelegateTemplateResolver ITemplateManager, e.g. DelegateTemplateManager, ResolvePathTemplateManager, EmbeddedResourceTemplateManager
    config.Resolver config.TemplateManager
    ResolveUsing(ITemplateResolver), ResolveUsing<TResolver>() ManageUsing(...), ManageUsing<TManager>() (ResolveUsing(Func<string, string>) stays)
    templateResolverType="..." in the configuration file templateManagerType="..."
    WrapperTemplateManager an ITemplateManager implementation

    A configuration file that still sets templateResolverType now fails to load with a ConfigurationErrorsException instead of being ignored.

  • (BREAKING) Code inspectors removed (obsolete since 3.5): ICodeInspector, the CodeInspectors properties of the compiler service and the configurations, AddInspector and Inspect(). There is no replacement. They were no security boundary either: templates must come from trusted sources.

  • (BREAKING) APIs announced for removal in 4.0 removed:

    • TemplateCompilationException.Errors: use CompilerErrors.
    • ICompilerService.IncludeAssemblies() and CompilerServiceBase.IncludeAssemblies(): use IncludeReferences().
    • The ExecuteContext(DynamicViewBag) constructor: it always threw; pass the view bag to Run/RunCompile instead.
    • The public TypeHash constructors of the embedded Impromptu code: use TypeHash.Create.
  • (BREAKING) VB.NET templates removed. Removed are Language.VisualBasic, the RazorEngine.Compilation.VisualBasic compiler services, CompilerServicesUtility.ResolveVBTypeName/VBGetRawTypeName/VBCreateGenericType, the VB parser in RazorEngineHost and the .vbhtml lookup of ResolvePathTemplateManager.

    • Templates are always C#. Convert .vbhtml templates to .cshtml.
    • A configuration file with language="VisualBasic" or defaultLanguage="VisualBasic" fails to load.
    • VB.NET applications can still use RazorEngine with C# templates and pass their own (also anonymous) objects as models.

Fixes

  • (BUGFIX) The Roslyn compiler service now prepares the generated code like the CodeDom one. Before, with Roslyn, base template types with constructor parameters failed to compile, dynamic models were not marked, and #line hidden was not removed for debugging.
  • (BUGFIX) The Roslyn compiler service now compiles optimized and defines RAZORENGINE, like CodeDom always did.

Build and tests

  • (BUILD) New tests check that both compilers optimize and define RAZORENGINE, compile modern C# (C# 6 to 8 samples) with Roslyn, and keep the CodeDom fallback tested.
  • (BUILD) The release workflow publishes tagged versions to nuget.org with trusted publishing (introduced for 4.0.0).
  • (PACKAGING) The copyright notice of the package and the assembly keeps the original project's notice and adds the fork's: Copyright © 2011-2017 RazorEngine Project, © 2026 RazorEngine.NetFramework contributors.

NuGet: https://www.nuget.org/packages/RazorEngine.NetFramework/4.1.0

RazorEngine.NetFramework 4.0.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 23:20
da7d5a6
  • (BREAKING) First release of the fork, published as the new package RazorEngine.NetFramework.
  • (SECURITY, BREAKING) Fix CVE-2021-46703 (sandbox escape in IsolatedRazorEngineService): IsolatedRazorEngineService and IsolatedTemplateService now refuse partially trusted (sandboxed) AppDomains with a NotSupportedException, because Code Access Security is no security boundary. Isolation with fully trusted AppDomains (to unload templates) works as before. Templates must come from trusted sources; see doc/Isolation.md.
  • (BREAKING) The assembly is now RazorEngine.NetFramework.dll, signed with a new key (public key token 58ad996d4f48e61f), so it no longer collides with the original RazorEngine.dll. Namespaces stay RazorEngine.*. When migrating, update app.config/web.config:
    • Change the assembly name of the section registration, e.g. type="RazorEngine.Configuration.RazorEngineConfigurationSection, RazorEngine.NetFramework".
    • Change every assembly-qualified type name inside <razorEngine> that names , RazorEngine (activatorType, baseTemplateType, cachingProviderType, compilerServiceFactoryType, encodedStringFactoryType, referenceResolverType, templateManagerType, templateResolverType).
    • Remove bindingRedirect entries for the old RazorEngine assembly.
  • (BUGFIX) The default reference resolver no longer passes the original RazorEngine/RazorEngine.Roslyn 3.x assemblies to the template compiler, so templates still compile when the original package is loaded in the same process.
  • (NEW) Roslyn is part of the package. In the original project it was the separate package RazorEngine.Roslyn (last 4.1.1-rc1); the fork contains the never-released upstream change from 3.10.1-alpha001 that merged it into the main assembly, so RoslynCompilerServiceFactory is available without another package. Remove RazorEngine.Roslyn when switching. CodeDom (csc.exe, C# 5) stays the default compiler in 4.0.0.
  • (PACKAGING) Because of that, the package now depends on Microsoft.CodeAnalysis.CSharp 1.3.2, System.Collections.Immutable 1.3.1 and System.Reflection.Metadata 1.4.2 in addition to Microsoft.AspNet.Razor (the original 3.10.0 only depended on Razor).
  • (NEW) Values in a DynamicViewBag are exchanged across AppDomains, so a view bag works with IsolatedRazorEngineService (never-released upstream change, thanks campersau, Antaris#504).
  • (BREAKING) Target .NET Framework 4.8 only. The net40 (Razor 2) and Razor4 (Microsoft.AspNetCore.Razor) builds are dropped.
  • (BUILD) SDK-style projects with NuGet PackageReference replace Paket and FAKE. Build with dotnet build, test with dotnet test, pack with dotnet pack.
  • (BUILD) GitHub Actions replace Travis CI and AppVeyor.
  • (PACKAGING) The package has the Apache-2.0 license expression, contains README and LICENSE, comes with a symbol package (.snupkg) on nuget.org and is built deterministically on GitHub Actions.
  • (BUILD) Releases are published from GitHub Actions: pushing a version tag builds, tests and packs that commit, pushes the package to nuget.org with trusted publishing and creates the GitHub release.
  • (BREAKING) Requires Microsoft.AspNet.Razor 3.3.0 (3.x maintenance release, the parser is unchanged since 3.2.3, so template syntax is unchanged from the 3.x net45 build). ASP.NET MVC 5.2.x only allows Razor below 3.3.0: apps using MVC have to update to Microsoft.AspNet.Mvc 5.3.0 (and Microsoft.AspNet.WebPages 3.3.0) to install this package, otherwise NuGet reports a version conflict (NU1107).
  • (PACKAGING) Depend on System.Security.Cryptography.X509Certificates 4.3.2 instead of the 4.1.0 pulled in by Roslyn. NuGet audit flags 4.1.0 for CVE-2017-11770, which only affects .NET Core, not .NET Framework; the pin keeps the audit warning away from consumers.
  • (BUILD) Tests use NUnit 5 (constraint model asserts), Moq 4.21 and Autofac 9; RazorEngine.Mvc uses Microsoft.AspNet.Mvc 5.3.0. Package versions are managed centrally in src/Directory.Packages.props.

NuGet: https://www.nuget.org/packages/RazorEngine.NetFramework/4.0.0