我应该使用多个正则表达式属性吗?

本文关键字:属性 正则表达式 我应该 | 更新日期: 2023-09-27 18:36:33

更新 8:这个问题有一个新的标题,希望它能帮助其他人避免耗时的错误......

我有以下代码:(您需要引用System.ComponentModel.DataAnnotations)

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var itemModelX = new MyModel() { Name = "1<d" };
            var contextX = new ValidationContext(itemModelX, serviceProvider: null, items: null);
            var resultsX = new List<ValidationResult>();
            var isValidX = Validator.TryValidateObject(itemModelX, contextX, resultsX, true);
            if (isValidX)
                Console.WriteLine("Should not see this");
            Console.WriteLine("Finished");
            Console.ReadLine();
        }
    }
    public class MyModel
    {
        [MultipleRegExAttribute2(@"[^?.]{1,100}$")]
        [MultipleRegExAttribute2(@"^((?![><&])['s'S])*$")]
        public string Name { get; set; }
    }
    [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = true)]
    public class MultipleRegExAttribute2 : RegularExpressionAttribute
    {
        public MultipleRegExAttribute2(string pattern) : base(pattern) { }
    }
}

在 Visual Studio 2013 Premium Update 5 中,输出为

"不应该看到这个"
"完了"

在 Visual Studio 2015 Enterprise Update 1 中,输出为

"完了"

罗斯林是正确的,问题是为什么 2013 年不起作用?
我很确定那是在 2013 年也工作了,不知道它什么时候坏了,我没有以前的更新来测试它......
我正在使用 .NET 4.5.1

更新 1
即使我删除了对System.ComponentModel.DataAnnotations的引用并将代码添加到我的项目中(你可以在这里找到代码),我也会得到不同的输出。

更新 2
忘了说它只发生在我有 2 个多个正则表达式属性的情况下,如果我删除第一个它按预期工作

更新 3我在这里上传了一个完整的解决方案

更新 4我检查了两个程序集生成的 IL,但我看到的唯一区别是一些局部变量的初始化

VS2015

.locals init (
    [0] class [System.ComponentModel.DataAnnotations]System.ComponentModel.DataAnnotations.ValidationContext contextX,
    [1] class [mscorlib]System.Collections.Generic.List`1<class [System.ComponentModel.DataAnnotations]System.ComponentModel.DataAnnotations.ValidationResult> resultsX             )

VS2013

.locals init (
    [0] class ConsoleApp.MyModel itemModelX,
    [1] class [System.ComponentModel.DataAnnotations]System.ComponentModel.DataAnnotations.ValidationContext contextX,
            [2] class [mscorlib]System.Collections.Generic.List`1<class [System.ComponentModel.DataAnnotations]System.ComponentModel.DataAnnotations.ValidationResult> resultsX,
            [3] bool isValidX,
            [4] class ConsoleApp.MyModel '<>g__initLocal0'
        )

更新 5
快到了。。。

  • VS2015只检查第二个属性(恰好是我在乎的情况下)
  • VS2013只检查第一个参数...

更新 6
几个小时后...
- 如果我有超过 1 个正则表达式属性
,似乎总是有问题 这可能是我的错误,因为我扩展了类并"覆盖"了 AllowMultiple

2.为什么用VS2015编译时得到的结果不一样?
返回属性的类是方法 GetProperties 中的 System.ComponentModel.TypeDescriptor。
我必须看看那里有什么变化...

更新 7
似乎有些东西在属性描述符/成员描述符返回属性的方式上发生了变化。
在VS2015中,它打印第二个正则表达式,在VS2013中打印第一个正则表达式。
那么,以下哪一项是正确的呢?

  • 一)这是一个实现细节,我不应该依赖这个
  • b)这是一个错误,因为它是一个重大更改
  • c)a 和 b
  • d)其他

.

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var property = TypeDescriptor.GetProperties(typeof(MyModel))[0];
            var attribute = property.Attributes.Cast<Attribute>();
            foreach (var item in attribute)
                if (item is MultipleRegExAttribute2)
                    Console.WriteLine(((MultipleRegExAttribute2)item).GetPattern());
            Console.ReadLine();
        }
    }
    public class MyModel
    {
        [MultipleRegExAttribute2(@"[^?.]{1,100}$")]
        [MultipleRegExAttribute2(@"^((?![><&])['s'S])*$")]
        public string Name { get; set; }
    }
    [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = true)]
    public class MultipleRegExAttribute2 : RegularExpressionAttribute
    {
        public MultipleRegExAttribute2(string pattern) : base(pattern) { }
        public string GetPattern() { return this.Pattern; }
    }
}

我应该使用多个正则表达式属性吗?

不要扩展 RegularExpressionAttribute 并将 AllowMultiple 设置为 true
它只会给你带来麻烦。

您可以创建 2 个从正则表达式属性继承的不同属性。

public class MyModel
{
    [MultipleRegExAttribute2(@"[^?.]{1,100}$")]
    [MultipleRegExAttribute3(@"^((?![><&])['s'S])*$")]
    public string Name { get; set; }
}

public class MultipleRegExAttribute2 : RegularExpressionAttribute
{
    public MultipleRegExAttribute2(string pattern) : base(pattern) { }
}

public class MultipleRegExAttribute3 : RegularExpressionAttribute
{
    public MultipleRegExAttribute3(string pattern) : base(pattern) { }
}

更新

我的一个朋友向我展示了问题的根源。
我必须重写 TypeId 属性。
请参阅此问题:具有多个实例的自定义验证属性问题
和这篇文章:TypeId 在 MVC 数据注释验证属性中的重要性 ASP.NET