ASP.NET Core MVC:如何在EditorFor/TextboxFor中渲染含总小时的TimeSpan
解决ASP.NET Core MVC中TimeSpan超24小时的可编辑格式化问题
要实现超过24小时的TimeSpan以「总小时:分钟」格式展示并支持编辑,需要自定义模型绑定器处理输入解析,配合自定义编辑器模板实现格式化显示,具体步骤如下:
1. 自定义TimeSpan模型绑定器
默认的ASP.NET Core TimeSpan绑定器不支持直接解析「总小时:分钟」格式(比如160:00),需要自己写绑定逻辑来解析输入字符串,转换为TimeSpan:
public class TotalHoursTimeSpanModelBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) throw new ArgumentNullException(nameof(bindingContext)); var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) return Task.CompletedTask; bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); var input = valueProviderResult.FirstValue; if (string.IsNullOrEmpty(input)) return Task.CompletedTask; // 解析「总小时:分钟」格式 if (input.Contains(':')) { var parts = input.Split(':'); if (parts.Length == 2 && int.TryParse(parts[0], out int totalHours) && int.TryParse(parts[1], out int minutes)) { if (minutes is >= 0 and <= 59) { bindingContext.Result = ModelBindingResult.Success(TimeSpan.FromHours(totalHours) + TimeSpan.FromMinutes(minutes)); return Task.CompletedTask; } } } // 解析失败,添加错误提示 bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "请输入有效的「总小时:分钟」格式(例如:160:00)"); return Task.CompletedTask; } }
2. 创建自定义编辑器模板
在Views/Shared/EditorTemplates目录下新建TimeSpanTotalHours.cshtml,用于控制EditorFor的渲染逻辑,实现格式化显示和输入:
@model TimeSpan? @{ var displayValue = Model.HasValue ? $"{(int)Model.Value.TotalHours}:{Model.Value.Minutes:D2}" : string.Empty; } @Html.TextBox("", displayValue, new { @class = "form-control", placeholder = "例如:160:00" })
3. 配置模型属性
在你的模型类中,给TimeSpan属性添加特性,指定绑定器和编辑器模板:
public class YourModel { [ModelBinder(BinderType = typeof(TotalHoursTimeSpanModelBinder))] [UIHint("TimeSpanTotalHours")] public TimeSpan TotalDuration { get; set; } }
4. 在视图中使用EditorFor
直接在视图里调用EditorFor即可自动应用自定义模板和绑定逻辑:
<div class="form-group"> <label asp-for="TotalDuration" class="control-label"></label> @Html.EditorFor(m => m.TotalDuration) <span asp-validation-for="TotalDuration" class="text-danger"></span> </div>
这样设置后,视图会以「总小时:分钟」格式展示TimeSpan值,用户输入符合格式的内容时,绑定器会自动解析为TimeSpan对象;如果输入格式错误,还会显示自定义的验证错误提示。
内容的提问来源于stack exchange,提问作者Yannick MOLINET
相关产品推荐
相关产品推荐

