ASP.NET Core 2中如何实现依赖上下文文化的正则验证注解?
动态文化适配的货币验证解决方案
好问题!先直接给你结论:不能直接用依赖上下文的常量作为RegularExpressionAttribute的属性值。因为C#中属性的参数必须是编译时常量(比如字符串字面量、const常量),而上下文文化是运行时才能确定的动态值,没法提前编译成常量传入。
不过别担心,我们可以通过自定义验证属性来实现这个需求,它能让你在验证逻辑里动态获取当前文化,适配对应的小数分隔符。下面是具体实现步骤:
1. 创建自定义货币验证属性
我们创建一个继承自ValidationAttribute的类,在IsValid方法里动态获取当前文化的小数分隔符,然后执行验证逻辑:
using System.Globalization; using System.ComponentModel.DataAnnotations; using System.Text.RegularExpressions; using Microsoft.AspNetCore.Http; public class CurrencyValidationAttribute : ValidationAttribute { // 基础的货币正则模板,把小数分隔符留空作为占位符 private const string CurrencyRegexTemplate = @"^[$]?\d+{0}?\d?\d? ?[€$]?$"; protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (value == null || string.IsNullOrWhiteSpace(value.ToString())) { // 允许空值,如果需要必填可以单独加[Required]属性 return ValidationResult.Success; } // 获取当前请求的文化信息 var httpContextAccessor = validationContext.GetService(typeof(IHttpContextAccessor)) as IHttpContextAccessor; var culture = httpContextAccessor?.HttpContext?.RequestCulture?.Culture ?? CultureInfo.CurrentCulture; var decimalSeparator = culture.NumberFormat.NumberDecimalSeparator; // 动态生成适配当前文化的正则表达式(转义分隔符避免正则语法冲突) var currencyRegex = string.Format(CurrencyRegexTemplate, Regex.Escape(decimalSeparator)); var regex = new Regex(currencyRegex); if (!regex.IsMatch(value.ToString())) { return new ValidationResult(ErrorMessage ?? "Invalid currency format"); } return ValidationResult.Success; } }
2. 注册IHttpContextAccessor(ASP.NET Core 2.x)
在Startup.cs的ConfigureServices里注册IHttpContextAccessor,这样我们才能在验证属性里获取当前请求的文化:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddHttpContextAccessor(); // 添加这一行注册服务 // 其他服务注册逻辑... }
3. 在模型中使用自定义属性
替换原来的[RegularExpression],用我们的自定义属性即可:
public class Record { [CurrencyValidation(ErrorMessage = "Invalid currency format")] public string Budget { get; set; } }
额外说明
- 客户端验证补充:如果需要客户端也支持动态文化验证,你需要自定义客户端验证逻辑(比如编写JS脚本,根据当前页面的文化动态生成正则),因为默认的客户端验证是基于静态正则的。
- 文化适配逻辑:如果你的项目通过路由、Cookie或其他方式设置请求文化,
RequestCulture会自动获取到对应的文化规则,不需要额外修改验证逻辑。 - 正则扩展:你可以根据需求调整正则模板,比如支持千位分隔符、更多货币符号等,只要在模板里替换对应的占位符即可。
内容的提问来源于stack exchange,提问作者serge
相关产品推荐
相关产品推荐

