自定义配置中的正则表达式部分工作

Regex in Custom Configuration Partially Working

我有一个 ConfigurationProperty,用 RegexStringValidator 注释,看起来像这样:

public class Test : ConfigurationElement
{
    [ConfigurationProperty("field", IsKey = true)]
    [RegexStringValidator("issuer|subject")]
    public string Field
    {
        get { return (string)base["field"]; }
    }
}

它总是抛出一个异常,提示 RegexStringValidator 失败。如果我将正则表达式值更改为以下任一值,我就能取得成功:

正在验证的实际 "field" 值是简单字符串 "issuer"。我看不出为什么会出现问题。事实上,the source code for RegexStringValidator 没什么特别的;它只是使用正则表达式并检查是否成功。

所以我试着直接做正则表达式作为测试,和里面做的一样RegexStringValidator:

Regex reg = new Regex(@"issuer|subject", RegexOptions.Compiled);
bool match = reg.Match("issuer").Success;

以上按预期工作;它 returns 成功==真。我什至使用 Telerik 的 "Just Decompile" 来验证 System.Configuration 源代码确实与在线发布的内容相匹配。

同样,我看不出为什么我的 "issuer|subject" RegexStringValidator 正则表达式总是失败。

有什么想法吗?

我找到的唯一线索是在尝试正则表达式“[a-zA-Z]”时。奇怪的是,这失败了,因为它没有尾随星号。因此,也许必须编写正则表达式以匹配输入的全长。为了验证该理论,我将我的正则表达式更改为“^issuer$|^subject$”,但在应用于 RegexStringValidator 时仍然不起作用。但是,它确实适用于我明确编写的正则表达式测试。

上述异常的有趣之处在于 RegexStringValidator 的源代码没有给出“[a-zA-Z]”失败的原因。这是否意味着我在网上反映和看到的代码与我机器上实际执行的代码不匹配?这似乎不太合理。所以这确实很奇怪......

我在安装了 .net 4.5 的机器上使用 .net 4.0 版本。

“[a-zA-Z]”失败并不奇怪。它不会匹配整个字符串。

你的问题的其余部分确实看起来很奇怪。可能会编写自己的代码,而不是在行为异常时依赖他人的代码?

你试过正则表达式吗

[RegexStringValidator("(issuer|subject)")]

我想通了。

当配置系统首次创建 ConfigurationElement 时,它会将每个 属性 初始化为空字符串。然后它会立即运行验证规则,包括正则表达式。空字符串与我的正则表达式不匹配,因此它在有机会将实际值分配给 属性.

之前就失败了

简而言之,.net 配置基础结构存在缺陷。

为了弥补这个缺陷,我添加了一个默认值和一个 IsRequired 要求:

public class Test : ConfigurationElement
{
    [ConfigurationProperty("field", IsKey = true, Default="issuer", IsRequired=true)]
    [RegexStringValidator("issuer|subject")]
    public string Field
    {
        get { return (string)base["field"]; }
    }
}

默认值允许 ConfigurationElement 初始化而不自动使正则表达式失败。不幸的是,这会产生不需要的副作用,因为我不想要默认值。所以我需要通过将 IsRequired 设置为 true 来补偿默认值。

这意味着用户现在被迫提供一个值,我的正则表达式将正确验证它。

顺便说一句,现在我明白了为什么正则表达式语句 [a-zA-Z]*.* 是 "successfull." 因为星号表示 "zero to many"。当 属性 被初始化为空字符串,并针对这两个正则表达式语句中的任何一个进行测试时,"zero" 要求挽救了这一天。当然那不是我想要的行为,但至少现在没有神秘感了。