我试图在我拥有的模型上验证属性。此属性不是必需的,因此如果其无效的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传递给此模型,则验证就好了。我究竟做错了什么?
答案 0 :(得分: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更改为不可为空的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更改为string
,然后仅在需要时将其转换为int
,我可以仅使用[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])
答案 1 :(得分: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)
答案 2 :(得分:0)
首先,您的模型应该实现IValidatableObject,但只有在ModelState有效时才会调用Validate方法。 This link can help。 您是否在行动中收到模型作为参数?你在问ModelState.IsValid吗?这应该适用于默认模型绑定器。
答案 3 :(得分:0)
我发现了一种我喜欢的解决方法。我遇到的问题是一个类似的问题,其中值必须大于0和一个数字,所以一旦我尝试将9999999999(无效)字符串转换为数字,它就抛出异常并且没有显示出来模型状态在帖子上有错误消息。我希望这是关于主题的,因为它听起来像#34;当我输入无效的数字&#34时,规则似乎没有正确应用"
由于我的数字必须是正数,我将该值截获为匿名类型对象(动态),并将其用作模型用户和私有int属性之间的拦截体。当我这样做时,数据注释按预期工作。
public dynamic MyProperty
{
get { return _myProperty; }
set
{
try
{
/ 我必须将值转换为String,因为它以String []的形式出现,如果有多个值,那么它应该是有问题的,所以你将它与无效字符一起加入并抛出一个错误,或者你取第一个值 / _myProperty = = Convert.ToInt32(String.Join(" a",value)); } catch(例外e) { _myProperty = -1; } } }
private int _myProperty;