4

我正在尝试验证我拥有的模型上的属性。此属性不是必需的,因此如果它的无效 MVC 似乎忽略它。我什至创建了一个自定义 ValidationAttribute,但没有任何效果。

public class NumberWang : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        if (value == null)
            return true;

        int g;
        if (int.TryParse(value.ToString(), out g))
        {
            if (g >= 0)
                return true;
        }
        return false;
    }
}

public class MyModel 
{
    [Range(0, 999999, ErrorMessage = "category_id must be a valid number")]
    [NumberWang(ErrorMessage = "That's NumberWang!")]
    public int? category_id { get; set; }

    /* there are other properties of course, but I've omitted them for simplicity */

    public void Validate()
    {
        Validator.TryValidateProperty(this.category_id,
        new ValidationContext(this, null, null) { MemberName = "category_id" },
        this.validation_results);
    }
}

如果我将值“abc”作为 category_id 传递给该模型,则它验证得很好。我究竟做错了什么?

4

4 回答 4

3

我发现了一个丑陋的解决方法。

似乎如果 category_id 是可空的int?并且我的值不是有效数字,则传递了一个空值,并且模型看不到无效的“abc”值。

[Range(0, 999999, ErrorMessage = "category_id must be a valid number")]
public int? category_id { get; set; }

// when we pass a good number
MyAction?category_id=123
validation: successful

// when we pass a bad number
// validation ignores it. not what we want. 
MyAction?category_id=abc
validation: successful

如果我将 category_id 更改为 non-nullable int,即使没有传递任何值,它也会失败验证。

[Range(0, 999999, ErrorMessage = "category_id must be a valid number")]
public int? category_id { get; set; }

// when we pass a good number
MyAction?category_id=123
validation: successful

// when we pass an bad number
MyAction?category_id=abc
validation: "category_id must be a valid number"

// BUT, when we don't pass any number at all ... 
MyAction 
validation: "category_id must be a valid number"

丑陋的解决方法

如果我将 category_id 更改为 a string,然后仅int在需要时将其转换为 an ,我可以正确验证它,仅使用[Range]

[Range(0, 999999, ErrorMessage = "category_id must be a valid number")]
public string category_id { get; set; }

// when we pass a good number
MyAction?category_id=123
validation: successful

// when we pass a bad number
MyAction?category_id=abc
validation: "category_id must be a valid number"

// no number, no validation. hooray!
MyAction 
validation: successful

这很丑陋,但它有效。

(注意:不需要自定义属性,所以我将其删除并仅使用 [Range])

于 2013-08-20T13:58:07.907 回答
1

模型:

// "(\s*[0-9]{0,6})" for 999999 max
// "(\s*[0-9]*)" for "infinite"
[RegularExpression(@"(\s*[0-9]{0,6})", ErrorMessage = "Field must be a natural number (max 999999)")]
public int? Quantity { get; set; }

看法:

@Html.TextBoxFor(m => m.Quantity)
@Html.ValidationMessageFor(m => m.Quantity)
于 2015-09-15T14:55:55.780 回答
0

首先,您的模型应该实现 IValidatableObject,但只有在 ModelState 有效时才会调用 Validate 方法。这个链接可以提供帮助。您是否将模型作为操作中的参数接收?你要的是 ModelState.IsValid 吗?这应该适用于默认模型绑定器。

于 2013-08-20T13:08:28.290 回答
0

我找到了一个我喜欢的解决方法。我遇到的问题是一个类似的问题,其中值必须大于 0 和一个数字,所以一旦我尝试将 9999999999(无效)字符串转换为数字,它就会抛出异常并且没有显示模型state 在帖子上有一条错误消息。我希望这是一个主题,因为它听起来像“当我输入无效数字时,规则似乎没有正确应用”

由于我的数字必须是正数,我将值截获到匿名类型对象(动态)中,并将其用作模型用户和私有 int 属性之间的截取体。当我这样做时,数据注释按预期工作。

    public dynamic MyProperty
    {
        get { return _myProperty; }
        set
        {
            try
            {

/我必须将值转换为String,因为它以String[]的形式出现,如果有多个值,那么它应该是有问题的,所以你将它与一个无效字符连接在一起并抛出一个错误,或者你采取第一个值/ _myProperty = = Convert.ToInt32(String.Join("a",value)); } 捕捉(异常 e){ _myProperty= -1; } } }

    private int _myProperty;
于 2016-11-29T19:26:27.513 回答