Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
430 views
in Technique[技术] by (71.8m points)

c# - Integer validation against non-required attributes in MVC

I've trying to validate a property on a model I have. This property is NOT required, and so if its invalid MVC seems to be ignoring it. I've even created a custom ValidationAttribute, but nothing works.

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);
    }
}

If I pass the value 'abc' as a category_id to this model, it validates just fine. What am I doing wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I found an ugly workaround.

It seems that if category_id is a nullable int? and my value is not a valid number, a null value is passed, and the model doesn't see the invalid 'abc' value.

[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

If I change category_id to a non-nullable int, it fails validation even when no value is passed.

[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"

The Ugly Workaround

If I change category_id to a string, and then only convert it to an int when I need it, I can validate it properly, using only [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

It's ugly, but it works.

(Note: the custom attribute was not needed, so I removed it and just used [Range])


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...