ASP.NET Core MVC(.NET 6)如何将视图中Double值传递至控制器
ASP.NET Core 6 MVC中Double值模型绑定异常的解决方法
你遇到的问题是.NET Core与传统ASP.NET Framework的配置差异导致的——.NET Core不再依赖Web.config的<globalization>节点,而是通过代码配置请求本地化或属性特性来处理数值解析的文化问题。以下是几种可行的解决方式:
方法一:全局配置请求本地化(推荐)
在Program.cs中添加请求本地化配置,指定服务器解析数值时使用的文化(比如en-GB,以点作为小数点分隔符),同时支持客户端文化:
// 添加本地化服务 builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); // 定义支持的文化列表 var supportedCultures = new[] { new CultureInfo("en-GB"), new CultureInfo("zh-CN"), // 根据业务需求添加其他文化 }; // 配置请求本地化中间件 app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture("en-GB"), // 默认使用en-GB解析 SupportedCultures = supportedCultures, SupportedUICultures = supportedCultures, // 若需要优先使用客户端传来的文化,可保留默认的RequestCultureProviders // 默认包含Cookie、Accept-Language头、查询参数等来源 });
配置后,服务器会按照指定的文化规则解析表单提交的数值,解决小数点分隔符不匹配的问题。
方法二:给模型属性添加特性(局部处理)
如果仅个别属性需要特殊处理,可以在实体类的double?属性上添加[DisplayFormat]特性,强制指定解析格式:
public class Material { public int Id { get; set; } public string? Name { get; set; } public int? Unit { get; set; } // 指定格式并允许在编辑模式下应用 [DisplayFormat(DataFormatString = "{0:F1}", ApplyFormatInEditMode = true)] public double? Count { get; set; } [DisplayFormat(DataFormatString = "{0:F2}", ApplyFormatInEditMode = true)] public double? Amount { get; set; } [DisplayFormat(DataFormatString = "{0:F2}", ApplyFormatInEditMode = true)] public double? Cost { get; set; } }
也可以结合[ModelBinder]特性指定绑定规则,或者使用CultureInfo.InvariantCulture确保解析一致性:
[DisplayFormat(DataFormatString = "{0:N}", ApplyFormatInEditMode = true, NullDisplayText = "")] public double? Count { get; set; }
方法三:自定义模型绑定器(兼容多种分隔符)
如果需要同时支持点和逗号作为小数点分隔符,可以自定义一个double类型的模型绑定器:
1. 创建自定义绑定器类
using Microsoft.AspNetCore.Mvc.ModelBinding; using System.Globalization; public class DoubleModelBinder : 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 inputValue = valueProviderResult.FirstValue; if (string.IsNullOrWhiteSpace(inputValue)) return Task.CompletedTask; // 将逗号替换为点,统一使用InvariantCulture解析 inputValue = inputValue.Replace(",", "."); if (double.TryParse(inputValue, NumberStyles.Any, CultureInfo.InvariantCulture, out var parsedValue)) { bindingContext.Result = ModelBindingResult.Success(parsedValue); } else { bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "请输入有效的数值格式"); } return Task.CompletedTask; } }
2. 注册绑定器
在Program.cs中注册自定义绑定器,使其生效:
builder.Services.AddControllersWithViews(options => { // 将自定义绑定器添加到绑定器提供者列表的最前面 options.ModelBinderProviders.Insert(0, new BinderTypeModelBinderProvider(typeof(DoubleModelBinder))); });
或者直接在属性上指定使用该绑定器:
[ModelBinder(BinderType = typeof(DoubleModelBinder))] public double? Count { get; set; }
内容的提问来源于stack exchange,提问作者dmmhlchk
相关产品推荐
相关产品推荐

