Blazor中如何经子组件传递属性表达式给Generic Input组件?
问题原因
当你在子组件的Razor模板中使用<GenericInput For="@For" />时,Blazor会自动将其编译为一个新的Expression<Func<T?>>,即() => this.For。这个新表达式的Body是访问子组件自身For属性的成员表达式,而非父组件传入的、指向_myDto.MyProperty的原始成员表达式,因此触发了GenericInput组件中For.Body is not MemberExpression的校验逻辑,抛出异常。
解决方案
要直接将父组件传入的表达式原样传递给GenericInput,需要绕过Blazor在Razor模板中自动包装表达式的行为,通过代码直接构建组件并传递参数:
子组件实现方式
@code { [Parameter] public Expression<Func<T?>>? For { get; set; } protected override void BuildRenderTree(RenderTreeBuilder builder) { // 直接构建GenericInput组件并传递原始表达式 builder.OpenComponent<GenericInput<T>>(0); builder.AddAttribute(1, nameof(GenericInput<T>.For), For); // 如需传递其他属性,可继续添加AddAttribute builder.CloseComponent(); } }
父组件使用方式保持不变
<ChildComponent For="() => _myDto.MyProperty"></ChildComponent>
这种方式通过RenderTreeBuilder直接将父组件传入的For表达式实例传递给GenericInput,不会生成新的包装表达式,因此能通过GenericInput的校验逻辑,正常渲染对应的输入框。
可选简化实现
如果你不想重写BuildRenderTree,也可以用RenderFragment在代码中直接渲染,确保表达式原样传递:
@{ RenderFragment renderInput = () => { var input = new GenericInput<T>(); input.For = For; return builder => input.BuildRenderTree(builder); }; } @renderInput @code { [Parameter] public Expression<Func<T?>>? For { get; set; } }
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

