You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor动态表单反射实现时字段名称前缀缺失问题修复咨询

问题修复:Blazor反射表单的字段命名与验证问题

问题根源

当前反射实现里,GetPropertyExpression方法用Expression.Constant(MyModel)创建表达式,这会让Blazor把字段绑定解析成直接引用模型实例的值,而非绑定到组件的MyModel属性。结果就是提交时字段名丢失MyModel前缀,同时验证系统没法正确关联模型属性的验证规则。

修复方案

修改GetPropertyExpression方法,生成指向组件MyModel属性的表达式,而非常量实例。这样Blazor就能生成带MyModel前缀的正确字段名,验证系统也能正常工作。

修改后的完整代码

@page "/login2"

@using System.ComponentModel.DataAnnotations
@using System.Linq.Expressions
@using System.Reflection

<EditForm Model="MyModel" FormName="LoginForm" OnValidSubmit="LoginUser">
    <DataAnnotationsValidator />

    @foreach (var prop in typeof(LoginModel).GetProperties())
    {
        var inputType = prop.Name == "Username" ? "text" : "password";

        <div>
            <InputText type="@inputType"
                       Value="@(GetPropertyValue<string>(prop))"
                       ValueChanged="val => SetPropertyValue(prop, val)"
                       ValueExpression="GetPropertyExpression<string>(prop)" />

            <ValidationMessage For="GetPropertyExpression<string>(prop)" />
        </div>
    }

    <button type="submit">
        Login
    </button>

</EditForm>

@code {
    [SupplyParameterFromForm]
    public required LoginModel MyModel { get; set; }

    protected override void OnInitialized() => MyModel ??= new();

    void LoginUser() { }

    public class LoginModel
    {
        [Required]
        public string? Username { get; set; }

        [Required]
        public string? Password { get; set; }
    }


    T? GetPropertyValue<T>(PropertyInfo prop) => (T?)prop.GetValue(MyModel, null);

    void SetPropertyValue(PropertyInfo prop, object? value) => prop.SetValue(MyModel, value);

    Expression<Func<T>> GetPropertyExpression<T>(PropertyInfo prop)
    {
        // 获取当前组件实例的表达式(this)
        var componentInstance = Expression.Constant(this);
        // 获取组件的MyModel属性
        var modelProperty = Expression.Property(componentInstance, nameof(MyModel));
        // 获取MyModel下的目标属性
        var targetProperty = Expression.Property(modelProperty, prop.Name);

        return Expression.Lambda<Func<T>>(targetProperty, Array.Empty<ParameterExpression>());
    }
}

关键修改说明

  • 把Expression.Constant(MyModel)替换为Expression.Property(Expression.Constant(this), nameof(MyModel)):让表达式指向组件的MyModel属性,而非当前的模型实例值。
  • 最终生成的表达式结构是() => this.MyModel.PropName,Blazor会据此生成正确的表单字段名(比如MyModel.Username),同时验证系统能正确关联LoginModel里定义的[Required]规则。

验证效果

修复后提交表单时,字段名将以MyModel为前缀,ValidationMessage也会根据模型的验证规则正确显示错误信息,和常规实现的行为完全一致。

内容的提问来源于stack exchange,提问作者Parsa99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 19:23:09