Blazor自定义InputText绑定decimal字段实现千位分隔符报类型转换错误如何解决
报错根因
所有报错的核心原因是现有自定义组件是为string类型绑定设计的:组件继承自InputBase<string>、ValidationFor参数也限定为string类型委托,当模型字段修改为decimal后,双方类型不匹配触发了转换报错。
完整修改方案
1. 重写自定义组件为支持decimal类型的专用组件
直接将组件调整为继承InputBase<decimal>,原生支持decimal类型绑定,同时保留千位分隔符的格式化逻辑:
@using System.Linq.Expressions @inherits InputBase<decimal> <div class=@ColumnLocation> @if (!string.IsNullOrWhiteSpace(Label)) { <label for="@Id">@Label</label> } <InputText @bind-Value="@CurrentValueAsString" class="form-control" placeholder="@Label"></InputText> <ValidationMessage For="@ValidationFor" /> </div> @code { [Parameter] public string Id { get; set; } [Parameter] public string Label { get; set; } // 修改参数类型为decimal对应的表达式 [Parameter] public Expression<Func<decimal>> ValidationFor { get; set; } [Parameter] public string ColumnLocation { get; set; } // 重写字符串转decimal逻辑:用户输入的带千分位的字符串转成decimal存到模型 protected override bool TryParseValueFromString(string value, out decimal result, out string validationErrorMessage) { // 先去掉输入里的千位分隔符逗号,避免解析失败 value = value?.Replace(",", "").Trim(); if (decimal.TryParse(value, out var parsedDecimal)) { result = parsedDecimal; validationErrorMessage = null; return true; } // 解析失败返回错误信息 result = default; validationErrorMessage = "请输入有效的数字"; return false; } // 重写decimal转字符串逻辑:模型里的decimal转成带千位分隔符的字符串显示在输入框 protected override string FormatValueAsString(decimal value) { return value.ToString("n2"); } }
2. 修改模型定义
将TotalQuoteCost调整为decimal类型,保留必填验证:
public class Quote { [Required(ErrorMessage = "报价成本不能为空")] [Range(typeof(decimal), "0", "9999999999.99", ErrorMessage = "请输入有效的金额范围")] public decimal TotalQuoteCost { get; set; } }
3. 页面调用代码无需额外改动,直接绑定decimal字段即可
@page "/counter" <EditForm Model="quote" OnValidSubmit="@SubmitButtonPressed" class="form-horizontal"> <DataAnnotationsValidator /> <UxInputText Label="Quote cost" @bind-Value="quote.TotalQuoteCost" ValidationFor="@(() => quote.TotalQuoteCost)" /> <button type="submit" class="btn">Check 1</button> <h1>@ttt</h1> </EditForm> @code { private string ttt = string.Empty; Quote quote = new Quote(); protected void SubmitButtonPressed() { ttt = quote.TotalQuoteCost.ToString(); } }
可选扩展
如果需要支持可空金额(允许字段为空),只需要把组件继承的基类改为InputBase<decimal?>,ValidationFor参数类型同步改为Expression<Func<decimal?>>,解析逻辑加空值判断即可。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

