【问题标题】:Data Annotations - How can I replace Range values with Web.Config values in MVC3?数据注释 - 如何在 MVC3 中用 Web.Config 值替换 Range 值?
【发布时间】:2011-10-20 23:11:19
【问题描述】:

如何在 MVC3 中将 Range 值替换为 Web.Config 值?

[Range(5, 20, ErrorMessage = "Initial Deposit should be between $5.00 and $20.00")
public decimal InitialDeposit { get; set; }

web.config:

<add key="MinBalance" value="5.00"/>
<add key="MaxDeposit" value="20.00"/>

【问题讨论】:

标签: asp.net-mvc asp.net-mvc-3


【解决方案1】:

您需要创建一个继承自RangeAttribute 并实现IClientValidatable 的自定义属性。

    public class ConfigRangeAttribute : RangeAttribute, IClientValidatable
    {
        public ConfigRangeAttribute(int Int) :
            base
            (Convert.ToInt32(WebConfigurationManager.AppSettings["IntMin"]),
             Convert.ToInt32(WebConfigurationManager.AppSettings["IntMax"])) { }

        public ConfigRangeAttribute(double Double) :
            base
            (Convert.ToDouble(WebConfigurationManager.AppSettings["DoubleMin"]),
             Convert.ToDouble(WebConfigurationManager.AppSettings["DoubleMax"])) 
        {
            _double = true;
        }

        private bool _double = false;

        public override string FormatErrorMessage(string name)
        {
            return String.Format(ErrorMessageString, name, this.Minimum, this.Maximum);
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = FormatErrorMessage(this.ErrorMessage),
                ValidationType = "range",
            };
            rule.ValidationParameters.Add("min", this.Minimum);
            rule.ValidationParameters.Add("max", this.Maximum);
            yield return rule;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null)
                return null;

            if (String.IsNullOrEmpty(value.ToString()))
                return null;

            if (_double)
            {
                var val = Convert.ToDouble(value);
                if (val >= Convert.ToDouble(this.Minimum) && val <= Convert.ToDouble(this.Maximum))
                    return null;
            }
            else
            {
                var val = Convert.ToInt32(value);
                if (val >= Convert.ToInt32(this.Minimum) && val <= Convert.ToInt32(this.Maximum))
                    return null;
            }

            return new ValidationResult(
                FormatErrorMessage(this.ErrorMessage)
            );
        }
    }

示例用法:

[ConfigRange(1)]
public int MyInt { get; set; }

[ConfigRange(1.1, ErrorMessage = "This one has gotta be between {1} and {2}!")]
public double MyDouble { get; set; }

第一个示例将返回默认错误消息,第二个示例将返回您的自定义错误消息。两者都将使用 web.config 中定义的范围值。

【讨论】:

  • 很高兴得到赞赏。 ;^> 谢谢,祝你好运。
  • @rk1962,好吧,不是天才。我快速查看了我的代码,发现我的服务器端验证测试是错误的。 :^O 我修复了IsValid() 函数中的错误行。请确保应用这些更改。
【解决方案2】:

您将无法在属性的属性声明中执行此操作,因为需要在编译时知道这些值。我能看到的最简单的方法是从RangeAttribute 派生一个属性类,并将属性值设置为来自派生类中的 web.config。类似的东西

public class RangeFromConfigurationAttribute : RangeAttribute
{
    public RangeFromConfigurationAttribute()
        : base(int.Parse(WebConfigurationManager.AppSettings["MinBalance"]), int.Parse(WebConfigurationManager.AppSettings["MaxDeposit"]))
    {

    }
}

可能想想出一个更好的名字:)

【讨论】:

  • 非常感谢。我刚刚用上面的代码创建了一个类,但它不起作用。我错过了什么吗?
  • 我看看能不能举个例子,虽然 Counsellorben 的代码看起来可以用 - stackoverflow.com/users/624472/counsellorben
  • @Russ Cam,很高兴有人注意到我的贡献。虽然你仍然得到了好东西。 ;)
  • 再次感谢 Russ Cam。辅导员本给出的解决方案效果很好!
【解决方案3】:

在这里大声思考,但 ConfigRange 属性规定必须存在配置才能使其正常工作。你能不能写一个静态类来从 web.config、app.config 或任何你认为合适的地方读取你的值,然后在现有的范围属性中使用那个静态类?

public static class RangeReader
{
    public static double Range1 
    {
        // Replace this with logic to read from config file
        get { return 20.0d; } 
    }        
}

然后使用以下命令注释您的属性:

[Range(ConfigReader.Range1, 25.0d)]

我知道静态类不好,可能有充分的理由不这样做,但我想我会试一试。

【讨论】:

  • 我在视图模型中没有任何编译错误,但没有机会通过将视图模型传递给视图来测试这一点。你还记得为什么这不起作用吗?
  • 我会再试一次,让你知道错误信息。谢谢!
  • 编译错误:属性参数必须是属性参数类型的常量表达式、typeof表达式或数组创建表达式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多