【问题标题】:MVC Model Validation UnobtrusiveMVC 模型验证不显眼
【发布时间】:2011-12-12 17:13:48
【问题描述】:

我正在使用 jquery 不显眼的方法在 UI 中验证我的模型。我在模型中有一个数字字段,我想将其验证为数字。开箱即用,它几乎可以正常工作。在验证 0.33 与 0.33 时,它在客户端失败。我知道我可以在 jquery 验证插件中更改正则表达式,但这似乎并不理想。

所以,为了尝试在不修改插件本身的情况下解决问题,我创建了以下验证属性:

public class DecimalValidator : System.ComponentModel.DataAnnotations.ValidationAttribute, System.Web.Mvc.IClientValidatable
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        decimal val = 0;
        ValidationResult ret = new ValidationResult("Must be a valid decimal");

        if (decimal.TryParse(value.ToString(), out val) )
            return ValidationResult.Success;
        else
            return ret;
    }


    #region IClientValidatable Members

    public System.Collections.Generic.IEnumerable<System.Web.Mvc.ModelClientValidationRule> GetClientValidationRules(System.Web.Mvc.ModelMetadata metadata, System.Web.Mvc.ControllerContext context)
    {
        List<System.Web.Mvc.ModelClientValidationRule> ret = new List<System.Web.Mvc.ModelClientValidationRule>();

        System.Web.Mvc.ModelClientValidationRule validDecimalRule = new System.Web.Mvc.ModelClientValidationRule
        {
            ErrorMessage = "Please enter a valid decimal.",
            ValidationType = "decimal"
        };

        ret.Add(validDecimalRule);

        return ret;
    }

    #endregion
}

并像这样应用它:

    /// <summary>
    /// The price per unit.
    /// </summary>
    [Range(0, double.MaxValue)]
    [Display(Name = "Price")]
    [DecimalValidator]
    public decimal UnitPrice { get; set; }

问题是html仍然呈现 data-val-number="价格字段必须是数字。" 除了新的, data-val-decimal="请输入有效的小数。"

如何防止呈现默认验证属性?

【问题讨论】:

    标签: javascript jquery model-view-controller validation


    【解决方案1】:

    我相信[Range(0, double.MaxValue)] 会强制它加载号码验证。 尝试将其添加到您的自定义验证器中并将其从您的字段装饰器中删除。

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        decimal val = 0;
        ValidationResult ret = new ValidationResult("Must be a valid decimal");
        ValidationResult rangeRet = new ValidationResult(String.Format("Number must be between 0 and {0}", double.MaxValue.ToString());
    
        if (decimal.TryParse(value.ToString(), out val) )
            return ValidationResult.Success;
        else if (value < 0 || value > double.MaxValue)
            return rangeRet;
        else
            return ret;
    }
    

    【讨论】:

    • 不,它也不是范围验证器。
    【解决方案2】:

    我发现答案是使用 $.extend 将插件中的数字验证替换为允许 .33 和 0.33 的正则表达式

    【讨论】:

    • 如果你去掉Range装饰器,我仍然很想知道是什么导致验证规则甚至出现在客户端上。不过,我还没有真正尝试过不显眼的验证插件,只有 jQuery 验证插件。
    【解决方案3】:

    为什么要创建自定义验证器?默认情况下,MVC 将为您验证。如果你让你的类型可以为空(十进制?),那么 MVC 会将 UnitPrice 设置为 null 如果输入了非十进制,并且如果你的模型状态违反了你正在做的任何其他验证,则使你的模型状态无效。

    【讨论】:

    • 他在他的问题中说为什么:“开箱即用,它几乎可以正常工作。在验证 0.33 与 0.33 时,它在客户端失败。”
    • @TerryR - 但事实并非如此,默认的模型绑定器将解析 .33 就好了,所以他一定是在谈论其他事情。
    • 是的,我没有验证这一点,我只是根据他的要求提供了一个解决方案。至少他现在有两条不同的路要走……
    • 问题表明问题出在客户端,而不是服务器端。
    • @Darthg8r - 我在哪里说过服务器端?开箱即用,如果您使用 decimal? 数据类型,它将使用不显眼的验证在服务器端和客户端正确验证 0.33。它“正常工作”。我已经对此进行了测试。那么,你为什么要草率地得出我说的是服务器端的结论呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多