首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Blazor RenderFragment参数转发给子组件引发异常

将Blazor RenderFragment参数转发给子组件引发异常
EN

Stack Overflow用户
提问于 2021-02-27 15:59:33
回答 2查看 899关注 0票数 2

更新: Microsoft已确认此问题。(Github issue),可能会在.Net 6 (github issue)中修复/解决。

我可以使用RenderFragment将(子)内容传递给组件。这可以是可选的。请看:

代码语言:javascript
复制
@*Baz.razor*@
@if (Bar is null)
{
    <div>nobar</div>
}
else
{
    <div>Render bar: @Bar</div>
}

@code {
    [Parameter]
    public RenderFragment Bar { get; set; }
}

我能做到

代码语言:javascript
复制
@*FooPage.razor*@
@page "/foopage"
<Baz />

,它呈现"nobar",或者

代码语言:javascript
复制
@*FooPage.razor*@
@page "/foopage"
<Baz Bar=@bar/>

@code {
    private RenderFragment bar = (builder) => { builder.AddMarkupContent(0, "<div>bar</div>"); };
}

这将呈现"Render bar: bar“(由于div而带有换行符)

所以,现在我有了一个新的情况,在这两者之间有一个组件,叫做Foo

代码语言:javascript
复制
@*Foo.razor*@
<Baz Bar=@Bar />

@code {
    [Parameter]
    public RenderFragment Bar { get; set; }
}

我将FooPage.razor修改为

代码语言:javascript
复制
@*FooPage.razor*@
@page "/foopage"
<Foo />

也就是说,我正在将Bar参数从Foo转发到Baz...这不起作用,并给了我一个相当长的错误(在这个问题的底部)。(注意:当我在FooPage中指定Bar时,它确实可以工作。)

这对我来说很奇怪。我可以检查Bar是否为空,并使用它或不使用它。但是,我不能显式地将Bar设置为null,或者传递null引用。

我也尝试过直接这样做:

代码语言:javascript
复制
@*FooPage.razor*@
@page "/foopage"
<Foo Bar=@nullrf />

@code {
    private RenderFragment nullrf;
}

这也抛出了相同的异常。

也就是说,如果你省略它,它就是空的,但是如果你给它赋值为空,它就会中断。这是一个bug吗?

代码语言:javascript
复制
ArgumentException: Delegate to an instance method cannot have null 'this'.
System.MulticastDelegate.ThrowNullThisInDelegateToInstance()
System.MulticastDelegate.CtorClosed(object target, IntPtr methodPtr)
BlazorServerDefault.Pages.Foo.BuildRenderTree(RenderTreeBuilder __builder)
Microsoft.AspNetCore.Components.ComponentBase.<.ctor>b__6_0(RenderTreeBuilder builder)
Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment)
Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry)
Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()
Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.HandleException(Exception exception)
Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()
Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessPendingRender()
Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(int componentId, RenderFragment renderFragment)
Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged()
Microsoft.AspNetCore.Components.ComponentBase.CallOnParametersSetAsync()
Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.HandleException(Exception exception)
Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToPendingTasks(Task task)
Microsoft.AspNetCore.Components.Rendering.ComponentState.SetDirectParameters(ParameterView parameters)
Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderRootComponentAsync(int componentId, ParameterView initialParameters)
Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.CreateInitialRenderAsync(Type componentType, ParameterView initialParameters)
Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.RenderComponentAsync(Type componentType, ParameterView initialParameters)
Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext+<>c__11<TResult>+<<InvokeAsync>b__11_0>d.MoveNext()
Microsoft.AspNetCore.Mvc.ViewFeatures.StaticComponentRenderer.PrerenderComponentAsync(ParameterView parameters, HttpContext httpContext, Type componentType)
Microsoft.AspNetCore.Mvc.ViewFeatures.ComponentRenderer.PrerenderedServerComponentAsync(HttpContext context, ServerComponentInvocationSequence invocationId, Type type, ParameterView parametersCollection)
Microsoft.AspNetCore.Mvc.ViewFeatures.ComponentRenderer.RenderComponentAsync(ViewContext viewContext, Type componentType, RenderMode renderMode, object parameters)
Microsoft.AspNetCore.Mvc.TagHelpers.ComponentTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.<RunAsync>g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, int i, int count)
BlazorServerDefault.Pages.Pages__Host.<ExecuteAsync>b__14_1() in _Host.cshtml
+
    <component type="typeof(App)" render-mode="ServerPrerendered" />
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
BlazorServerDefault.Pages.Pages__Host.ExecuteAsync() in _Host.cshtml
+
    Layout = null;
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, bool invokeViewStarts)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0<TFilter, TFilterAsync>(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
EN

Stack Overflow用户

发布于 2021-03-02 05:53:57

这不是真正的答案,但我需要一些地方放一些代码,这比评论更好。

问题出在为razor组件构建适当的类时,Razor代码被预编译成BuildRenderTree方法的方式。怪罪于组件构建器。你需要以Razor期望的方式声明RenderFragments。

您的编码-使用属性方法:

代码语言:javascript
复制
<Baz Bar="@Bar"></Baz>

Razor构建器将其转换为:

代码语言:javascript
复制
    public partial class Foo2 : Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
            __builder.OpenComponent<TestBlazorServer.Components.Bar>(0);
            __builder.AddAttribute(1, "Bar", 
#nullable restore
          Bar

#line default
#line hidden
#nullable disable
            );
            __builder.CloseComponent();
        }
        #pragma warning restore 1998
#nullable restore
#line 3        
    [Parameter]
    public RenderFragment Bar { get; set; }

请注意,Bar是作为属性添加的,如上面的答案所述。

现在,如果您像这样声明它:

代码语言:javascript
复制
<Baz>
 <Bar>@Bar</Bar>
</Baz>

Bar被正确地添加为RenderFragment时,您会得到这样的结果。

代码语言:javascript
复制
    public partial class Foo : Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
            __builder.OpenComponent<TestBlazorServer.Components.Bar>(0);
            __builder.AddAttribute(1, "Baz", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
                __builder2.AddContent(2, 
#nullable restore
#line 5          
Bar

#line default
#line hidden
#nullable disable
                );
            }
            ));
            __builder.CloseComponent();
        }
        #pragma warning restore 1998
#nullable restore
#line 9        
    [Parameter]
    public RenderFragment Bar { get; set; }

这是我几个月前在代码中构建组件时遇到的问题。无论如何,我不确定你是否可以用这种方式构建你的东西,但它解释了你所看到的。

票数 2
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66396746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档