You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:14:40