【问题标题】:Dynamic expression as data-annotations attribute values作为数据注释属性值的动态表达式
【发布时间】:2018-01-15 12:50:48
【问题描述】:

我有一个 ASP.NET Core 2 项目,我在其中使用注释来验证货币字段,如下所示:

public class Record {
    public const string CurrencyRegex = @"^[$]?\d+[,.]?\d?\d? ?[€$]?$";

[RegularExpression(Record.CurrencyRegex, ErrorMessage = "Invalid currency format")]
public string Budget { get; set; }

问题是小数点分隔符 ([,.]?\d?\d?) 并不完美。我需要表达对当前语境文化的理解。如果是英国/美国,则小数分隔符应验证为.,但在此处的 id,例如 FR 文化,小数应视为 ,

如果可能,我如何使用“上下文相关常量”作为RegularExpression 属性值?

【问题讨论】:

    标签: c# validation asp.net-core asp.net-core-2.0 globalization


    【解决方案1】:

    这是不可能的。传递给属性的任何值都必须是编译时常量。但Thread.CurrentThread.CurrentCulture 或类似名称是运行时变量。

    您可以将Budget 定义为decimaldouble,并让ModelBinder 使用当前区域性解析输入字符串。 (您必须在附加字段中传输货币符号。)

    或者通过在模型上实现IValidatableObject来处理验证并删除[RegularExpression]

    using System.Globalization;
    using System.Text.RegularExpressions;
    
    public class Record : IValidatableObject {
    
         public string Budget { get; set; }
    
         public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
    
            var currentDecimalSeparator =
                CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    
            // no need to espace literal dot '.' 
            // because it is used inside a character class '[.]'
            var currencyPattern = @"^[$]?\d+[" + currentDecimalSeparator + @"]?\d?\d? ?[€$]?$";
    
            if (!Regex.IsMatch(Budget, currencyPattern)) {
                 yield return new ValidationResult(
                     $"Invalid currency format (use '{currentDecimalSeparator}' for decimal places).",
                     new[] { "Budget" }
                 );
            }
         }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-22
      • 2018-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 2015-03-04
      相关资源
      最近更新 更多