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
相关产品推荐
相关产品推荐

