dotnet / razor

Compiler and tooling experience for Razor ASP.NET Core apps in Visual Studio, Visual Studio for Mac, and VS Code.
https://asp.net
MIT License
498 stars 191 forks source link

Blazor compile fails with 'The name 'context' does not exist in the current context' when markup returned from a method #7638

Closed Kikimora closed 9 months ago

Kikimora commented 3 years ago

Describe the bug

Blazor compiler does fails when markup returned form a method contains reference to '@context'.

To Reproduce

See this Blazor Fiddle. In this fiddle I start by rendering simple component with 'RowTemplate'

<Test Data="@MyData">
    <RowTemplate><p style="font-color:red">@context</p></RowTemplate>
</Test>

Then I verify that I can return markup from a method

@WorksFine()
/*
    private RenderFragment WorksFine()
    {
        return @<p>Hello Fragment</p>;
    }
/*

Then I try to return 'Test' component from a method and it fails

    @CompileError()
/*
    private RenderFragment CompileError()
    {
        return @<Test Data="@MyData">
                    <RowTemplate><p style="font-color:red">@context</p></RowTemplate>
                </Test>;
    }
*

Exceptions (if any)

Compile error - Index.razor(26,61): error CS0103: The name 'context' does not exist in the current context

Further technical details

Runtime Environment: OS Name: Mac OS X OS Version: 10.15 OS Platform: Darwin RID: osx.10.15-x64 Base Path: /usr/local/share/dotnet/sdk/5.0.100/

Host (useful for support): Version: 5.0.0 Commit: cf258a14b7

.NET SDKs installed: 3.1.404 [/usr/local/share/dotnet/sdk] 5.0.100 [/usr/local/share/dotnet/sdk]

.NET runtimes installed: Microsoft.AspNetCore.App 3.1.10 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.10 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Kikimora commented 3 years ago

This is sample solution that trigger the problem.

After a bit of investigation I found this. When Blazor sees

<Test Data="@MyData"><RowTemplate ...>@context<RowTemplate></Test>

inside 'normal' Razor markup it generates a call to AddAttribute like this

builder.AddAttribute(..., context => builder2 => ...); //No problem here, 'context' passed as a lambda argument

But when it encounter same markup inside a method it generates

builder.OpenElement("RowTemplate"); 
builder.AddContent(..., context); //This is a compile error, no 'context' defined.

as if 'RowTemplate' was a child of 'Test' component.

To workaround this problem 'RowTemplate' can be passed explicitly as an attribute.

//This fails
//    RenderFragment TestWithContextFail() => @<Test Data="@TestData" RowTemplate="@RowTemplate()">
//                                            <RowTemplate><p style="color: green">@context</p></RowTemplate>
//                                        </Test>;

//This works, note how RowTemplate passed as an attribute, not a child content
    RenderFragment TestWithContextSuccess() => @<Test Data="@TestData" RowTemplate="@RowTemplate()"/>;

    RenderFragment<string> RowTemplate() => context => @<p style="color: blue">@context</p>;
Kikimora commented 3 years ago

@javiercn I see you have market this as 'blazor-wasm' but it fails in the same way with Blazor Server as well.

javiercn commented 3 years ago

@Kikimora thanks for contacting us.

It's just muscle memory :), but yes, this is a general compiler issue, which will also affect SSB

mkArtakMSFT commented 3 years ago

@ajaybhargavb can you please look into this? Thanks!

ghost commented 3 years ago

Thanks for contacting us. We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

ghost commented 2 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

TanayParikh commented 2 years ago

Putting into backlog due to limited community engagement in this issue.

edgarwideman commented 9 months ago

2024, this is still an issue

jjonescz commented 9 months ago

Can repro in .NET 5 but seems to be working fine in .NET 6 and newer.

tommyvct commented 6 months ago

To whoever have this problem in 2024, you may have accidentally deleted something from the _Imports.razor.

For me, it's @using Microsoft.AspNetCore.Components.Authorization.

Commit frequently and analyze differences may work.