C# 使用动态值而不是固定值的范围属性

C# 使用动态值而不是固定值的范围属性,c#,.net,asp.net-mvc,C#,.net,Asp.net Mvc,我想在mvc viewmodel中使用数据注释范围属性。问题是这个范围属性应该是动态值 我的viewmodel还具有ValueOne和ValueTwo属性。基于这个值,我想设置范围属性。价值观 [Range(1, 1000, ErrorMessage = "Value for {0} must be between {1} and {2}.")] 其中1和1000应替换为ValueOne和ValueTwo属性值 所以我尝试了自定义属性 public class ValidateCustomA

我想在mvc viewmodel中使用数据注释范围属性。问题是这个范围属性应该是动态值

我的viewmodel还具有ValueOne和ValueTwo属性。基于这个值,我想设置范围属性。价值观

 [Range(1, 1000, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
其中1和1000应替换为ValueOne和ValueTwo属性值

所以我尝试了自定义属性

public class ValidateCustomAttribute: ValidationAttribute
    {
        private readonly double _MinValue = 0;
        private readonly double _MaxValue = 100;

        public override bool IsValid(object value)
        {
            double val = (double)value;
            return val >= _MinValue && val <= _MaxValue;
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format(ErrorMessage, _MinValue, _MaxValue);
        }
    }

使用动态值(我的viewmodel中的ValueOne和ValueTwo)。

这无法完成,属性中不能有变量。属性值必须在编译时已知


请参见此和一个。

只需添加一个构造函数:

private double _MinValue, _MaxValue; // no readonly keyword

public ValidateCustomAttribute(double min, double max, Func<string> errorMessageAccessor)
    : base(errorMessageAccessor)
{
    _MinValue = min;
    _MaxValue = max;
}
但如果在代码中使用文字(或常量),则可以使用以下内容:

[ValidateCustom(1, 1000)]
在另一个类或方法上:

[ValidateCustom(3, 45)]
您缺少的是接受这些静态值并将它们附加到您用属性描述的构造的构造函数


编辑:解决这一问题的丑陋方式

如果你真的需要这个,你可以绕过限制,但它是丑陋的,因为它可以得到。我强烈反对这件事,但你自找的

  • 对数据进行分类
  • 将类别映射到绑定符号
  • 使用绑定符号
  • 将绑定符号解析为数据
  • 那么,让我们开始工作:

    1) 对数据进行分类

    比如说,您的数据是一个范围
    (min,max)
    ,首先要确定哪些值是可能的,假设您有4个可能的范围(可能是数百个,但这是另一个问题)

    2) 将类别映射到绑定符号

    现在您必须使用
    enum
    作为这些范围的绑定符号:

    public enum MyRanges
    {
        R1, R2, R3, R4
    }
    
    3) 使用绑定符号

    将构造函数定义为接受绑定符号:

    4) 将绑定符号解析为数据

    最后您需要的是一个包含实际数据的字典:

    Dictionary<MyRanges, double> dataMin = {
        { MyRanges.R1, 1},
        { MyRanges.R2, 10},
        { MyRanges.R3, 3},
        { MyRanges.R4, 5}
    };
    
    Dictionary<MyRanges, double> dataMax = {
        { MyRanges.R1, 1000},
        { MyRanges.R2, 20},
        { MyRanges.R3, 45},
        { MyRanges.R4, 7}
    };
    
    完成了

    现在不能更改的是从属性到类别的绑定,但是类别中包含的数据可以自由更改


    但是丑陋而且不可能维持。真的不要这样做。

    你可以这样做:

    [ValidateCustom(MyRanges.R2, "ERROR!")]
    
    public class MinimumAgeAttribute : RangeAttribute
    {
        public static string MinimumValue => ConfigurationManager.AppSettings["your key"];
        public static string MaxValue => ConfigurationManager.AppSettings["your key"];
    
        public CustomRangeAttribute(Type type):base(type,MaxValue , MinimumValue)
        {
        }
    
    }
    
    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomRangeAttribute),
                typeof(RangeAttributeAdapter));
    
    [CustomRange(typeof(DateTime), ErrorMessage = "You message")]
    public DateTime DateOfBirth { get; set; }
    
    在此之后,您必须在Global.asax中注册属性,如下所示:

    [ValidateCustom(MyRanges.R2, "ERROR!")]
    
    public class MinimumAgeAttribute : RangeAttribute
    {
        public static string MinimumValue => ConfigurationManager.AppSettings["your key"];
        public static string MaxValue => ConfigurationManager.AppSettings["your key"];
    
        public CustomRangeAttribute(Type type):base(type,MaxValue , MinimumValue)
        {
        }
    
    }
    
    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomRangeAttribute),
                typeof(RangeAttributeAdapter));
    
    [CustomRange(typeof(DateTime), ErrorMessage = "You message")]
    public DateTime DateOfBirth { get; set; }
    
    在此之后,您可以像这样使用它:

    [ValidateCustom(MyRanges.R2, "ERROR!")]
    
    public class MinimumAgeAttribute : RangeAttribute
    {
        public static string MinimumValue => ConfigurationManager.AppSettings["your key"];
        public static string MaxValue => ConfigurationManager.AppSettings["your key"];
    
        public CustomRangeAttribute(Type type):base(type,MaxValue , MinimumValue)
        {
        }
    
    }
    
    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomRangeAttribute),
                typeof(RangeAttributeAdapter));
    
    [CustomRange(typeof(DateTime), ErrorMessage = "You message")]
    public DateTime DateOfBirth { get; set; }
    

    我不明白,[ValidateCustom(11000)]没有做我想做的事情。这也是标准值的范围,我需要动态值的范围。如果我错了,请详细说明。当程序集加载到内存中时,会计算(执行)属性。从那时起,元数据就不能更改(这将是元编程)。你可以绕过这个问题,但它是丑陋的。我会在5分钟内给你做一次编辑。