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

Blazor EditForm使用嵌套类实现分步表单验证遇错求助

Blazor EditForm分步表单嵌套类验证问题

背景

原本使用单个类作为EditForm的模型进行服务端验证,代码如下:

原始工作代码

C#模型类

public class NewProgramInput
{
    [Required]
    public string? Name { get; set; }

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

Razor表单代码

<EditForm Model="@NewProgramInput" OnValidSubmit="(() => SubmitForm())">
    <div>
        <InputText class="input" @bind-Value="NewProgramInput.Name" />
        <ValidationMessage For="(() => NewProgramInput.Name)"></ValidationMessage>
    </div>
    <div>
        <InputText class="input" @bind-Value="NewProgramInput.Email" />
        <ValidationMessage For="(() => NewProgramInput.Email)"></ValidationMessage>
    </div>
</EditForm>

由于实际表单规模较大,希望拆分为多个步骤。尝试用嵌套类来组织各步骤的属性以提升可读性,但运行时出错。

尝试的嵌套类写法

C#模型类

public class NewProgramInput
{
    public class Step1
    {
        [Required]
        public string? Name { get; set; }
    }

    public class Step2
    {
        [Required]
        public string? Email { get; set; }
    }
}

Razor分步表单代码

@if (Step == 1)
{
    <EditForm Model="@NewProgramInput.Step1" OnValidSubmit="(() => SubmitForm())">
        <div>
            <InputText class="input" @bind-Value="NewProgramInput.Step1.Name" />
            <ValidationMessage For="(() => NewProgramInput.Step1.Name)"></ValidationMessage>
        </div>
    </EditForm>
}

@if (Step == 2)
{
    <EditForm Model="@NewProgramInput.Step2" OnValidSubmit="(() => SubmitForm())">
        <div>
            <InputText class="input" @bind-Value="NewProgramInput.Step2.Email" />
            <ValidationMessage For="(() => NewProgramInput.Step2.Email)"></ValidationMessage>
        </div>
    </EditForm>
}

报错信息

NewProgramInput.Step1 is a type, which is not valid in the given context.

问题

这种嵌套类的方式是否不可行,还是存在操作疏漏?


解决方案

问题出在你把嵌套类的类型直接当成了实例对象来使用。EditForm的Model参数需要接收一个对象实例,而不是类型本身。

修正后的模型类

在主类中声明嵌套类的实例属性,而不是仅定义嵌套类类型:

public class NewProgramInput
{
    // 创建嵌套类的实例,作为主类的属性
    public Step1 Step1 { get; set; } = new Step1();
    public Step2 Step2 { get; set; } = new Step2();

    public class Step1
    {
        [Required]
        public string? Name { get; set; }
    }

    public class Step2
    {
        [Required]
        public string? Email { get; set; }
    }
}

修正后的Razor代码

确保绑定的是实例对象而非类型,同时补充必要的初始化和步骤切换逻辑:

@if (Step == 1)
{
    <EditForm Model="@NewProgramInput.Step1" OnValidSubmit="SubmitForm">
        <div>
            <InputText class="input" @bind-Value="NewProgramInput.Step1.Name" />
            <ValidationMessage For="(() => NewProgramInput.Step1.Name)"></ValidationMessage>
        </div>
        <button type="submit">进入第二步</button>
    </EditForm>
}

@if (Step == 2)
{
    <EditForm Model="@NewProgramInput.Step2" OnValidSubmit="SubmitForm">
        <div>
            <InputText class="input" @bind-Value="NewProgramInput.Step2.Email" />
            <ValidationMessage For="(() => NewProgramInput.Step2.Email)"></ValidationMessage>
        </div>
        <button type="submit">提交表单</button>
    </EditForm>
}

@code {
    // 初始化主模型实例
    private NewProgramInput NewProgramInput { get; set; } = new NewProgramInput();
    private int Step { get; set; } = 1;

    private void SubmitForm()
    {
        if (Step == 1)
        {
            Step = 2;
        }
        else
        {
            // 处理最终提交逻辑,例如将数据提交到后端
        }
    }
}

关键说明

  • 嵌套类本身是可行的,但必须在主类中创建其实例,才能作为EditForm的Model绑定。
  • 修正后既保留了嵌套类的结构可读性,又符合Blazor对表单模型的要求(必须是对象实例)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 09:47:51