Blazor自定义InputBase组件TryParseValueFromString未触发求助
问题:Blazor自定义InputBase组件的TryParseValueFromString方法未触发
我基于Blazor University教程、Stack Overflow及GitHub相关内容,创建了一个继承自InputBase<int?>的自定义组件。组件显示正常,但提交表单时,自定义验证方法TryParseValueFromString从未触发,断点完全没命中,导致验证消息无法传递到编辑上下文,也无法显示。因为后续要实现复杂验证,没法依赖DataAnnotations验证,所以需要解决这个方法在输入不可解析值时的触发问题。
更新说明
- 将Blazor University的教程文件直接加入项目后,同样的方法也未触发,这似乎是个普遍问题。
- 在VS2022中创建全新的.NET8 Blazor Server原生项目并添加相同页面,问题依旧存在。
页面代码
@page "/" @using BlazorAppTryParseValueFromString.Component @using static Microsoft.AspNetCore.Components.Web.RenderMode @rendermode InteractiveServer <PageTitle>Index</PageTitle> <EditForm Model="myModel" OnValidSubmit="FormSubmit"> <ValidationSummary /> <p> <IntegerComponent @bind-Value=myModel.MyNumber /> </p> <p> <input type="submit" value="Go" /> <ValidationMessage For="() => myModel.MyNumber" /> </p> <p> @Result </p> </EditForm> @code { public class MyModel { public int? MyNumber { get; set; } } public string Result { get; set; } = ""; public MyModel myModel { get; set; } = new(); public async void FormSubmit() { string yourNumber = myModel.MyNumber.HasValue ? myModel.MyNumber.Value.ToString() : "nothing"; Result = $"Your number was {yourNumber}"; } }
组件代码
@inherits InputBase<int?> <div> <input type="text" @bind=CurrentValue /> </div> @code { protected override bool TryParseValueFromString(string? value, out int? result, out string validationErrorMessage) { validationErrorMessage = ""; result = null; if (string.IsNullOrWhiteSpace(value)) { return true; } int parsedInt; if (!int.TryParse(value.Trim(), out parsedInt)) { validationErrorMessage = "Invalid value!"; return false; } result = parsedInt; return true; } }
解决方案
问题出在使用@bind=CurrentValue的方式上,这种绑定会直接使用双向绑定的默认逻辑,绕过了InputBase的解析和验证流程。需要改用InputBase提供的标准绑定方式,手动处理输入事件并调用CurrentValueAsString来触发解析逻辑。
修改后的组件代码如下:
@inherits InputBase<int?> <div> <input type="text" value="@CurrentValueAsString" @oninput="HandleInput" /> </div> @code { private void HandleInput(ChangeEventArgs e) { CurrentValueAsString = e.Value?.ToString(); } protected override bool TryParseValueFromString(string? value, out int? result, out string validationErrorMessage) { validationErrorMessage = ""; result = null; if (string.IsNullOrWhiteSpace(value)) { return true; } if (!int.TryParse(value.Trim(), out var parsedInt)) { validationErrorMessage = "无效数值!"; return false; } result = parsedInt; return true; } }
关键修改点
- 不再使用
@bind=CurrentValue,而是手动绑定value到CurrentValueAsString,并通过@oninput事件更新这个属性。 CurrentValueAsString是InputBase提供的核心属性,当它被赋值时,会自动调用TryParseValueFromString方法进行解析和验证,验证结果会自动同步到编辑上下文,触发ValidationMessage和ValidationSummary的显示。- 这样修改后,无论在输入过程中还是提交表单时,只要输入内容变化,都会触发自定义的解析验证逻辑,断点也能正常命中。
额外说明
如果需要仅在失去焦点时触发验证,可以把@oninput换成@onchange,这样只会在输入框失去焦点或用户按下回车时执行解析验证。
内容的提问来源于stack exchange,提问作者EvilDr
相关产品推荐
相关产品推荐

