RazorLight: The name 'section' does not exist in the current context in .net core 3

Describe the bug Since upgrading to the latest version of Razorlight official release (I was using unofficial before) I am experience the issue that sections aren’t working anymore. I keep getting the error: The name 'section' does not exist in the current context.

To Reproduce I am working on a unit test which coverage this breakage

Expected behavior

Information (please complete the following information):

  • OS: Ubuntu
  • Platform .net Core 3.0
  • RazorLight version 2.0-beta4
  • Are you using the OFFICIAL RazorLight package? Yes
  • Visual Studio version I am using Rider 2019.3

Additional context I had to upgrade from the unofficial package to the official beta 4 because it has net core 3 support before I was using the .net core 2.2 which worked happilly

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 4
  • Comments: 28

Most upvoted comments

Thanks for your efforts on this project.

Just wondering if there has there been any progress on this issue? Seems can’t use RazorLight version 2.0-beta4 in .net core 3.1 if you define a @section ?

Can you show me a repro? Is this problem related to sections or should you open a new issue so we can discuss your problems there? Thanks.

I have this working in my local and the fix is shockingly simple that I’m disappointed I didn’t put more effort in earlier to fix it. But I hope you’ll all give me a pass given COVID-19.

I have a workaround for this. First, you creating custom engine builder:

CustomRazorLightEngineBuilder

public class CustomRazorLightEngineBuilder : RazorLightEngineBuilder
    {
        public override RazorLightEngine Build()
        {
            var options = new RazorLightOptions();

            if (namespaces != null)
            {
                options.Namespaces = namespaces;
            }

            if (dynamicTemplates != null)
            {
                options.DynamicTemplates = dynamicTemplates;
            }

            if (metadataReferences != null)
            {
                options.AdditionalMetadataReferences = metadataReferences;
            }

            if (excludedAssemblies != null)
            {
                options.ExcludedAssemblies = excludedAssemblies;
            }

            if (prerenderCallbacks != null)
            {
                options.PreRenderCallbacks = prerenderCallbacks;
            }

            if (cachingProvider != null)
            {
                options.CachingProvider = cachingProvider;
            }

            //options.DisableEncoding = disableEncoding;


            var metadataReferenceManager = new DefaultMetadataReferenceManager(options.AdditionalMetadataReferences, options.ExcludedAssemblies);
            var assembly = operatingAssembly ?? Assembly.GetEntryAssembly();
            var compiler = new RoslynCompilationService(metadataReferenceManager, assembly);

            var sourceGenerator = new RazorSourceGenerator(CustomRazorEngine.Instance, project, options.Namespaces);
            var templateCompiler = new RazorTemplateCompiler(sourceGenerator, compiler, project, options);
            var templateFactoryProvider = new TemplateFactoryProvider();

            var engineHandler = new EngineHandler(options, templateCompiler, templateFactoryProvider, cachingProvider);

            return new RazorLightEngine(engineHandler);
        }
    }

Second, you copy DefaultRazorEngine to your code and change Instance field implementation to this:

CustomRazorEngine


public static RazorEngine Instance
        {
            get
            {
                var configuration = RazorConfiguration.Default;
                var razorProjectEngine = RazorProjectEngine.Create(configuration, new NullRazorProjectFileSystem(), builder =>
                {
                    RazorLight.Instrumentation.InjectDirective.Register(builder);
                    RazorLight.Instrumentation.ModelDirective.Register(builder);

                    //In RazorLanguageVersion > 3.0 (at least netcore 3.0) the directives are registed out of the box.
                    if (!RazorLanguageVersion.TryParse("3.0", out var razorLanguageVersion)
                        || configuration.LanguageVersion.CompareTo(razorLanguageVersion) < 0)
                    {
                        NamespaceDirective.Register(builder);
                        FunctionsDirective.Register(builder);
                        InheritsDirective.Register(builder);
                        SectionDirective.Register(builder);
                    }
                    var sectionDirective = builder.Features.OfType<SectionDirectivePass>().FirstOrDefault();
                    if (sectionDirective == null)
                    {
                        SectionDirective.Register(builder);
                    }

                    builder.Features.Add(new ModelExpressionPass());
                    builder.Features.Add(new RazorLightTemplateDocumentClassifierPass());
                    builder.Features.Add(new RazorLightAssemblyAttributeInjectionPass());
                   \\#if NETSTANDARD2_0
		   builder.Features.Add(new InstrumentationPass());
                   \\#endif
                    //builder.Features.Add(new ViewComponentTagHelperPass());

                    builder.AddTargetExtension(new Microsoft.AspNetCore.Razor.Language.Extensions.TemplateTargetExtension()
                    {
                        TemplateTypeName = "global::RazorLight.Razor.RazorLightHelperResult",
                    });

                    OverrideRuntimeNodeWriterTemplateTypeNamePhase.Register(builder);
                });

                return razorProjectEngine.Engine;
            }
        }

Note the following piece of code:

var sectionDirective = builder.Features.OfType<SectionDirectivePass>().FirstOrDefault();
if (sectionDirective == null)
{
    SectionDirective.Register(builder);
}

And you also have to copy OverrideRuntimeNodeWriterTemplateTypeNamePhase to your project.

Now you can use CustomRazorLightEngineBuilder that will produce correct engine setup.

@ADNewsom09 You refactored a lot of section tags in 2 hours and 30 minutes? You must be really fast typer!

lol thanks, apparently the person that wrote the templates used them all over but they weren’t using them to do much. A quick script to just remove the text “@section XXXXX {” and the corresponding “}” throughout the app got my proof of concept dot net core 3.1 branch working.

I plan to sort through this stuff. I just have vacation coming up Feb 1-9 so trying to get my projects done before then. As always, this is unpaid time, so if it’s not a pain point for me, it’s not urgent.

I had separately reached out to the maintainer of the Snapper library so PR #309 could advance forward.