RazorLight: An Include stops Layout being rendered

A template renders fine if it has a Layout and two sections defined. However, as soon as I add an “include” it completely ignores the Layout and sections and only renders the actual content of the template plus the “include”

Steps to reproduce the behavior: So this renders fine:

@{
    Layout = "14"; // Simple Razor Layout
}
@section HEADER {
    @{ await IncludeAsync("16");  }
}
@section FOOTER {
    @{ await IncludeAsync("7");  }
}
<p>
  This is THE BODY of the template.
</p>

Whilst adding this at the end:

@{ await IncludeAsync("10"); }

causes it to ignore the Layout and HEADER and FOOTER sections and just renders the content of the

plust the contents of the include with Id 10. (Those Ids represent IDs in a database, loaded using the override of GetItemAsync of RazorLightProject class.

Expected behaviour: It should render all the tags as in the first case plus add the content of the Include ID 10 to the rendered body of the template.

Information (please complete the following information):

  • Win 10
  • NET Standard 2.0
  • RazorLight version - the latest code as on 1/2/2019 which should correspond to 2.0-beta1 but does not really seem to since, as already reported, the Cache.Remove does not remove the cached compiled template so I needed to fix that. By switching my reference to the project instead of the DLL from the Nuget package, I found that there are actually changes in the organization of the caching classes so the Nuget does not represent the current latest code.

I’m still looking into how to fix this behaviour, seeing that the project seems to be dormant for the past 8 months so I can’t expect a fix soon probably, but since I do not know exactly how the in-place compilation works I’ve already spent a few hours on that, found that the generated code looks fine, but then the generated assembly only calls RazorLight for the one Include for some reason. I do not see how that may be caused by the RaorLight code, but I obviously am just not seeing that as the generated code seems to be fine as already mentioned.

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 1
  • Comments: 19 (1 by maintainers)

Most upvoted comments

OK, so I’ve spent more time on this yesterday and today trying to make it work. I did find where the problem is, but I am not able to solve it because:

  1. It seems to be caused by a (very) different result in the GeneratedCode property from the call to Microsoft.AspNetCore.Razor.Language.DefaultRazorCodeDocument.GetCSharpDocument.
  2. I have no idea if and how to influence the result from that call.

For testing, I have a simplified template with only one layout containing one optional section called HEADER:

@{
    Layout = "36"; /* Test main layout */
}


@section HEADER {
<div>
  TEST <i>HEADER</i>
</div>
}

<p>
  Hello there,
</p>
<p>
  BLA BLA BLAH
</p>
<p>
  Best regards,<br><br>  
  from us.
</p>

The test layout content:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  </head>
  <body>
    @RenderSection("HEADER", required: false)
    <hr />
    @RenderBody()
  </body>
</html>

This compiles only when the “@section HEADER { ... }” part is left out. If it is included it results in “error CS0103: The name 'section' does not exist in the current context.” after the call to compilation.Emit in the CompileAndEmit function body where the “result.Success” is FALSE.

The obvious reason for this is the aforementioned result for the GeneratedCode from the GetCSharpDocument call, which when run under .NET Core 3.1 returns the following from the source HTML template:

#pragma checksum "22" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "a463ecc46c7005fb78c6115266c4dad8e348fa6d"
// <auto-generated/>
#pragma warning disable 1591
[assembly:global::RazorLight.Razor.RazorLightTemplateAttribute(@"22", typeof(RazorLight.CompiledTemplates.GeneratedTemplate))]
namespace RazorLight.CompiledTemplates
{
    #line hidden
    public class GeneratedTemplate : global::RazorLight.TemplatePage<dynamic>
    {
        #pragma warning disable 1998
        public async override global::System.Threading.Tasks.Task ExecuteAsync()
        {
#nullable restore
#line 1 "22"
  
    Layout = "36"; 

#line default
#line hidden
#nullable disable
            WriteLiteral("\n\n");
#nullable restore
#line 6 "22"
Write(section);

#line default
#line hidden
#nullable disable
            WriteLiteral(" HEADER {\n<div>\n  HEADER\n</div>\n}\n\n<p>\n  Hello there,\n</p>\n<p>\n  BLA BLA BLAH\n</p>\n<p>\n  Best regards,<br><br>  \n  the TipOff.Stream team.\n</p>");
        }
        #pragma warning restore 1998
    }
}
#pragma warning restore 1591

(Notice the Write(section).)

For comparison, the same call to that function in .NET Core 2.1 returns this:

#pragma checksum "22" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "c1485ef954197a844195e602fb01c1a49c5f8597"
// <auto-generated/>
#pragma warning disable 1591
[assembly:global::RazorLight.Razor.RazorLightTemplateAttribute(@"22", typeof(RazorLight.CompiledTemplates.GeneratedTemplate))]
namespace RazorLight.CompiledTemplates
{
    #line hidden
    public class GeneratedTemplate : global::RazorLight.TemplatePage<dynamic>
    {
        #pragma warning disable 1998
        public async override global::System.Threading.Tasks.Task ExecuteAsync()
        {
#line 1 "22"
  
    Layout = "36"; /* Test main layout */

#line default
#line hidden
            BeginContext(47, 2, true);
            WriteLiteral("\n\n");
            EndContext();
            DefineSection("HEADER", async() => {
                BeginContext(66, 23, true);
                WriteLiteral("\n<div>\n  HEADER\n</div>\n");
                EndContext();
            }
            );
            BeginContext(91, 109, true);
            WriteLiteral("\n<p>\n  Hello there,\n</p>\n<p>\n  BLA BLA BLAH\n</p>\n<p>\n  Best regards,<br><br>  \n  the TipOff.Stream team.\n</p>");
            EndContext();
        }
        #pragma warning restore 1998
    }
}
#pragma warning restore 1591

where you can clearly see the DefineSection("HEADER", async() => { ... } that is missing from the 3.1 version and which is replaced there with the Write(section) and the WriteLiteral (" ... " ) contains the string “HEADER” twice there, which also seems to be quite clearly wrong.

Can anybody fix this behavior somehow? Any ideas @jzabroski or @toddams ?

@toddams I ran into this same issue. Is there any expectation for a new version of RazorLight soon? A few other issues are cropping up i.e. #134