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

时间:2015-07-31 22:08:26

标签: c# .net regex configuration

我的ConfigurationProperty注释了RegexStringValidator,如下所示:

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

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

  • "[a-zA-Z]*"
  • ".*"

实际"字段"被验证的值是简单的字符串"发行者"。我没有理由认为应该有问题。事实上,the source code for RegexStringValidator没有任何幻想;它只是使用正则表达式并检查是否成功。

所以我尝试直接将regex作为测试,就像在RegexStringValidator内完成一样:

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

以上工作符合预期;它返回Success == true。我甚至使用过Telerik" Just Decompile"验证System.Configuration源代码确实匹配在线发布的内容。

同样,我看不出我的发行人|主题" RegexStringValidator正则表达式不断失败。

有什么想法吗?

我出现的唯一线索就是我尝试了正则表达式#34; [a-zA-Z]"。奇怪的是,这失败了,因为它没有尾随的星号。因此,可能必须编写正则表达式以匹配输入的全长。为了测试这个理论,我将我的正则表达式更改为" ^ issuer $ | ^ subject $",但在应用于RegexStringValidator时仍然无法正常工作。但是,它确实适用于我明确编写的正则表达式测试。

使上述异常变得有趣的原因是RegexStringValidator的源代码没有说明为什么" [a-zA-Z]"会失败的。这是否意味着我在线反映和看到的代码与我机器上实际执行的代码不匹配?这看起来似乎不合理。所以这确实很奇怪......

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

3 个答案:

答案 0 :(得分:1)

我明白了。

当配置系统首次创建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]*.*是“成功的”。这是因为星号表示“从零到多”。当属性初始化为空字符串,并针对这两个正则表达式语句中的任何一个进行测试时,“零”要求可以保存当天。当然这不是我想要的行为,但至少现在没有什么神秘感。

答案 1 :(得分:0)

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

你问题的其余部分确实看起来很奇怪。也许编写自己的代码而不是依赖别人的代码,当它表现得很奇怪时?

答案 2 :(得分:0)

你是否尝试过reg表达式

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