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
495 stars 191 forks source link

Microsoft.CodeAnalysis.Razor cannot compile events of native element #9494

Open zxyao145 opened 11 months ago

zxyao145 commented 11 months ago

Hi, I try using Microsoft.CodeAnalysis.Razor compiles Razor code, but it does not take effect for native element events. What is the reason for this?

the RazorProjectEngine:

var projectEngine = RazorProjectEngine.Create(config, fileSystem, builder =>
{
    builder.SetRootNamespace(options.RootNamespace);
    builder.AddDefaultImports(options.DefaultImports);

    CompilerFeatures.Register(builder);
    builder.Features.Add(new CompilationTagHelperFeature());
    builder.Features.Add(new DefaultMetadataReferenceFeature
    {
        References = _references
    });
});

razor source:

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

the generate c# code:

 #pragma checksum "/App/App.razor" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "655ee4e28de9d4b7c3fdf299bc1b5d27e86b1701"
// <auto-generated/>
#pragma warning disable 1591
namespace AntDesignDemo.App
{
    #line hidden
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Components;
    public partial class App : Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
            __builder.AddMarkupContent(0, "<h1>Counter</h1>\r\n\r\n");
            __builder.OpenElement(1, "p");
            __builder.AddAttribute(2, "role", "status");
            __builder.AddContent(3, "Current count: ");
#nullable restore
#line 3 "/App/App.razor"
__builder.AddContent(4, currentCount);

#line default
#line hidden
#nullable disable
            __builder.CloseElement();
            __builder.AddMarkupContent(5, "\r\n\r\n");
            __builder.AddMarkupContent(6, "<button class=\"btn btn-primary\" @onclick=\"IncrementCount\">Click me</button>");
        }
        #pragma warning restore 1998
#nullable restore
#line 7 "/App/App.razor"

    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }

#line default
#line hidden
#nullable disable
    }
}
#pragma warning restore 1591
 }

and the Rendered results: image

chsienki commented 11 months ago

CompilerFeatures.Register(builder); conditionally adds features depending on the language version. What version do you have set in config

zxyao145 commented 11 months ago

CompilerFeatures.Register(builder); conditionally adds features depending on the language version. What version do you have set in config CompilerFeatures.Register(builder); 根据语言版本有条件地添加功能。你设置 config 了什么版本

RazorLanguageVersion.Latest.

var config = RazorConfiguration.Create(
    RazorLanguageVersion.Latest,
    configurationName: "Blazor",
    extensions: Array.Empty<RazorExtension>());
_projectEngine = RazorProjectEngine.Create(config, fileSystem, builder =>
{
    builder.SetRootNamespace(options.RootNamespace);
    builder.AddDefaultImports(options.DefaultImports);

    CompilerFeatures.Register(builder);

    builder.Features.Add(new CompilationTagHelperFeature());
    builder.Features.Add(new DefaultMetadataReferenceFeature
    {
        References = _references
    });
});

And amazingly, for Blazor components, events can be handled correctly:

image

zxyao145 commented 11 months ago

I have found the reason, @using Microsoft.AspNetCore.Components.Web must be added to the default import, or appear in the code like this:

+ @using Microsoft.AspNetCore.Components.Web

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}
ScarletKuro commented 3 months ago

I have another problem. I'm using similar code as the author, specifically this: https://github.com/MudBlazor/TryMudBlazor/blob/main/src/Try.Core/CompilationService.cs However, the new bindings @bind:get, @bind:set, @bind:after do not work.

<h1>Bind Get Set Examples</h1>

<h2>Elements</h2>

<input type="text" @bind:get="text" @bind:set="(value) => { text = value; }" />
<input type="text" @bind:get="text" @bind:set="Set" />
<input type="text" @bind:get="text" @bind:set="SetAsync" />

@text

@code {
    private string text = "test";

    private void Set(string value)
    {
        text = value;
    }

    private Task SetAsync(string value)
    {
        text = value;
        return Task.CompletedTask;
    }
}

The issue is that while the code compiles, the bindings do not work. However, it works fine in a normal Blazor project. Does anyone have an idea of what might be missing? All the necessary using statements seem to be in place and the library versions are the latest.

ScarletKuro commented 3 months ago

However, the new bindings @bind:get, @bind:set, @bind:after do not work.

I see that the ComponentBindLoweringPass is added, which I believe is responsible for that feature. This makes me even more confused about why it doesn't work.

List of features ```javascript - Items Microsoft.AspNetCore.Razor.Language.IRazorFeature[55] Microsoft.AspNetCore.Razor.Language.IRazorFeature[] + 0 Microsoft.AspNetCore.Razor.Language.DefaultImportProjectFeature Microsoft.AspNetCore.Razor.Language.DefaultImportProjectFeature + 1 Microsoft.AspNetCore.Razor.Language.DefaultRazorDirectiveFeature Microsoft.AspNetCore.Razor.Language.DefaultRazorDirectiveFeature + 2 Microsoft.AspNetCore.Razor.Language.Extensions.DefaultMetadataIdentifierFeature Microsoft.AspNetCore.Razor.Language.Extensions.DefaultMetadataIdentifierFeature + 3 Microsoft.AspNetCore.Razor.Language.DefaultRazorParserOptionsFactoryProjectFeature Microsoft.AspNetCore.Razor.Language.DefaultRazorParserOptionsFactoryProjectFeature + 4 Microsoft.AspNetCore.Razor.Language.DefaultRazorCodeGenerationOptionsFactoryProjectFeature Microsoft.AspNetCore.Razor.Language.DefaultRazorCodeGenerationOptionsFactoryProjectFeature + 5 Microsoft.AspNetCore.Razor.Language.DefaultRazorParserOptionsFeature Microsoft.AspNetCore.Razor.Language.DefaultRazorParserOptionsFeature + 6 Microsoft.AspNetCore.Razor.Language.DefaultRazorCodeGenerationOptionsFeature Microsoft.AspNetCore.Razor.Language.DefaultRazorCodeGenerationOptionsFeature + 7 Microsoft.AspNetCore.Razor.Language.DefaultDirectiveSyntaxTreePass Microsoft.AspNetCore.Razor.Language.DefaultDirectiveSyntaxTreePass + 8 Microsoft.AspNetCore.Razor.Language.HtmlNodeOptimizationPass Microsoft.AspNetCore.Razor.Language.HtmlNodeOptimizationPass + 9 Microsoft.AspNetCore.Razor.Language.DefaultDocumentClassifierPass Microsoft.AspNetCore.Razor.Language.DefaultDocumentClassifierPass + 10 Microsoft.AspNetCore.Razor.Language.Extensions.MetadataAttributePass Microsoft.AspNetCore.Razor.Language.Extensions.MetadataAttributePass + 11 Microsoft.AspNetCore.Razor.Language.Extensions.DesignTimeDirectivePass Microsoft.AspNetCore.Razor.Language.Extensions.DesignTimeDirectivePass + 12 Microsoft.AspNetCore.Razor.Language.DirectiveRemovalOptimizationPass Microsoft.AspNetCore.Razor.Language.DirectiveRemovalOptimizationPass + 13 Microsoft.AspNetCore.Razor.Language.Extensions.DefaultTagHelperOptimizationPass Microsoft.AspNetCore.Razor.Language.Extensions.DefaultTagHelperOptimizationPass + 14 Microsoft.AspNetCore.Razor.Language.Extensions.PreallocatedTagHelperAttributeOptimizationPass Microsoft.AspNetCore.Razor.Language.Extensions.PreallocatedTagHelperAttributeOptimizationPass + 15 Microsoft.AspNetCore.Razor.Language.Extensions.EliminateMethodBodyPass Microsoft.AspNetCore.Razor.Language.Extensions.EliminateMethodBodyPass + 16 Microsoft.AspNetCore.Razor.Language.DefaultRazorTargetExtensionFeature Microsoft.AspNetCore.Razor.Language.DefaultRazorTargetExtensionFeature + 17 Microsoft.AspNetCore.Razor.Language.DefaultDocumentClassifierPassFeature Microsoft.AspNetCore.Razor.Language.DefaultDocumentClassifierPassFeature + 18 Microsoft.AspNetCore.Razor.Language.Extensions.ViewCssScopePass Microsoft.AspNetCore.Razor.Language.Extensions.ViewCssScopePass + 19 Microsoft.AspNetCore.Razor.Language.Extensions.FunctionsDirectivePass Microsoft.AspNetCore.Razor.Language.Extensions.FunctionsDirectivePass + 20 Microsoft.AspNetCore.Razor.Language.Extensions.ImplementsDirectivePass Microsoft.AspNetCore.Razor.Language.Extensions.ImplementsDirectivePass + 21 Microsoft.AspNetCore.Razor.Language.Extensions.InheritsDirectivePass Microsoft.AspNetCore.Razor.Language.Extensions.InheritsDirectivePass + 22 Microsoft.AspNetCore.Razor.Language.Extensions.AttributeDirectivePass Microsoft.AspNetCore.Razor.Language.Extensions.AttributeDirectivePass + 23 Microsoft.AspNetCore.Razor.Language.Components.ComponentImportProjectFeature Microsoft.AspNetCore.Razor.Language.Components.ComponentImportProjectFeature + 24 Microsoft.AspNetCore.Razor.Language.Components.ComponentInjectDirectivePass Microsoft.AspNetCore.Razor.Language.Components.ComponentInjectDirectivePass + 25 Microsoft.AspNetCore.Razor.Language.Components.ComponentLayoutDirectivePass Microsoft.AspNetCore.Razor.Language.Components.ComponentLayoutDirectivePass + 26 Microsoft.AspNetCore.Razor.Language.Components.ComponentPageDirectivePass Microsoft.AspNetCore.Razor.Language.Components.ComponentPageDirectivePass + 27 Microsoft.AspNetCore.Razor.Language.Components.ComponentDocumentClassifierPass Microsoft.AspNetCore.Razor.Language.Components.ComponentDocumentClassifierPass + 28 Microsoft.AspNetCore.Razor.Language.Components.ComponentWhitespacePass Microsoft.AspNetCore.Razor.Language.Components.ComponentWhitespacePass + 29 Microsoft.AspNetCore.Razor.Language.Components.ComponentComplexAttributeContentPass Microsoft.AspNetCore.Razor.Language.Components.ComponentComplexAttributeContentPass + 30 Microsoft.AspNetCore.Razor.Language.Components.ComponentLoweringPass Microsoft.AspNetCore.Razor.Language.Components.ComponentLoweringPass + 31 Microsoft.AspNetCore.Razor.Language.Components.ComponentScriptTagPass Microsoft.AspNetCore.Razor.Language.Components.ComponentScriptTagPass + 32 Microsoft.AspNetCore.Razor.Language.Components.ComponentEventHandlerLoweringPass Microsoft.AspNetCore.Razor.Language.Components.ComponentEventHandlerLoweringPass + 33 Microsoft.AspNetCore.Razor.Language.Components.ComponentKeyLoweringPass Microsoft.AspNetCore.Razor.Language.Components.ComponentKeyLoweringPass + 34 Microsoft.AspNetCore.Razor.Language.Components.ComponentReferenceCaptureLoweringPass Microsoft.AspNetCore.Razor.Language.Components.ComponentReferenceCaptureLoweringPass + 35 Microsoft.AspNetCore.Razor.Language.Components.ComponentSplatLoweringPass Microsoft.AspNetCore.Razor.Language.Components.ComponentSplatLoweringPass + 36 Microsoft.AspNetCore.Razor.Language.Components.ComponentBindLoweringPass Microsoft.AspNetCore.Razor.Language.Components.ComponentBindLoweringPass + 37 Microsoft.AspNetCore.Razor.Language.Components.ComponentCssScopePass Microsoft.AspNetCore.Razor.Language.Components.ComponentCssScopePass + 38 Microsoft.AspNetCore.Razor.Language.Components.ComponentTemplateDiagnosticPass Microsoft.AspNetCore.Razor.Language.Components.ComponentTemplateDiagnosticPass + 39 Microsoft.AspNetCore.Razor.Language.Components.ComponentGenericTypePass Microsoft.AspNetCore.Razor.Language.Components.ComponentGenericTypePass + 40 Microsoft.AspNetCore.Razor.Language.Components.ComponentChildContentDiagnosticPass Microsoft.AspNetCore.Razor.Language.Components.ComponentChildContentDiagnosticPass + 41 Microsoft.AspNetCore.Razor.Language.Components.ComponentMarkupDiagnosticPass Microsoft.AspNetCore.Razor.Language.Components.ComponentMarkupDiagnosticPass + 42 Microsoft.AspNetCore.Razor.Language.Components.ComponentMarkupBlockPass Microsoft.AspNetCore.Razor.Language.Components.ComponentMarkupBlockPass + 43 Microsoft.AspNetCore.Razor.Language.Components.ComponentMarkupEncodingPass Microsoft.AspNetCore.Razor.Language.Components.ComponentMarkupEncodingPass + 44 Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilderExtensions.ConfigureRootNamespaceFeature Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilderExtensions.ConfigureRootNamespaceFeature + 45 Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilderExtensions.AdditionalImportsProjectFeature Microsoft.AspNetCore.Razor.Language.RazorProjectEngineBuilderExtensions.AdditionalImportsProjectFeature + 46 Microsoft.CodeAnalysis.Razor.BindTagHelperDescriptorProvider Microsoft.CodeAnalysis.Razor.BindTagHelperDescriptorProvider + 47 Microsoft.CodeAnalysis.Razor.ComponentTagHelperDescriptorProvider Microsoft.CodeAnalysis.Razor.ComponentTagHelperDescriptorProvider + 48 Microsoft.CodeAnalysis.Razor.EventHandlerTagHelperDescriptorProvider Microsoft.CodeAnalysis.Razor.EventHandlerTagHelperDescriptorProvider + 49 Microsoft.CodeAnalysis.Razor.RefTagHelperDescriptorProvider Microsoft.CodeAnalysis.Razor.RefTagHelperDescriptorProvider + 50 Microsoft.CodeAnalysis.Razor.KeyTagHelperDescriptorProvider Microsoft.CodeAnalysis.Razor.KeyTagHelperDescriptorProvider + 51 Microsoft.CodeAnalysis.Razor.SplatTagHelperDescriptorProvider Microsoft.CodeAnalysis.Razor.SplatTagHelperDescriptorProvider + 52 Microsoft.CodeAnalysis.Razor.DefaultTypeNameFeature Microsoft.CodeAnalysis.Razor.DefaultTypeNameFeature + 53 Microsoft.CodeAnalysis.Razor.CompilationTagHelperFeature Microsoft.CodeAnalysis.Razor.CompilationTagHelperFeature + 54 Microsoft.CodeAnalysis.Razor.DefaultMetadataReferenceFeature Microsoft.CodeAnalysis.Razor.DefaultMetadataReferenceFeature length 55 number ```