I need to use Range Validator in my asp.net mvc 4 project. In view model I added:
我需要在我的asp.net mvc 4项目中使用Range Validator。在视图模型中,我添加了:
[Range(0, int.MaxValue, ErrorMessage = "The Region field is required.")]
public int Region { get; set; }
And in controller i checked it by ModelState.IsValid
.
在控制器中,我通过ModelState.IsValid检查它。
The problem is ModelState don't accept 0
as a properly value - it's strange because I set range from 0
to max int
, so I thought that 0
belong to collection (like in MVC 5 if I remember). Am I wrong or it's just a bug? Any others value is reading properly (-1
is not accepting and 1001
is ok).
问题是ModelState不接受0作为正确的值 - 这很奇怪,因为我设置范围从0到最大int,所以我认为0属于集合(如果我记得就像在MVC 5中)。我错了还是只是一个错误?任何其他值都正确读取(-1不接受,1001可以)。
UPDATE 1
(Like you see in above pictures I don't anything with my model before I not check if model is valid).
(就像你在上面的图片中看到的那样,在我不检查模型是否有效之前,我对我的模型没有任何意义)。
Register method:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
//I was never here! Always ModelState.IsValid returns false
}
// If we got this far, something failed, redisplay form
ViewBag.Regions = _database.Department.ToList();
return View(model);
}
Full RegisterViewModel class:
完整的RegisterViewModel类:
public class RegisterModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[Display(Name = "Role")]
public int Role { get; set; }
[Range(0, int.MaxValue, ErrorMessage = "The Region field is required.")]
[Display(Name = "Region")]
public int Region { get; set; }
}
Register view:
<fieldset>
<legend>Registration Form</legend>
<ol>
<li>
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.PasswordFor(m => m.Password)
</li>
<li>
@Html.LabelFor(m => m.ConfirmPassword)
@Html.PasswordFor(m => m.ConfirmPassword)
</li>
<li>
@Html.LabelFor(m => m.Role)
<select id="Role" name="Role" data-val-required="The Role field is required." data-val="true">
<option value="">Choose role for user</option>
<option value="1">Administrator</option>
<option value="2">Inspector</option>
</select>
</li>
<li id="region-section">
@Html.LabelFor(m => m.Region)
<select id="Region" name="Region" data-val-required="The Region field is required." data-val="true">
<option value="" selected>Choose region</option>
@foreach (var item in ViewBag.Regions)
{
<option value="@item.Id">@item.Name</option>
}
</select>
</li>
</ol>
<input type="submit" value="Register" />
</fieldset>
UPDATE 2
According to @pilotcam advice I have used ValidateModel()
function. In debug mode I got HResult: -2146233079
- I was trying convert it into System Error Code (-2146233079 & 0xFFFF = 5385
) but is not a part of System Error Codes list.
根据@pilotcam的建议,我使用了ValidateModel()函数。在调试模式下,我得到了HResult:-2146233079 - 我试图将其转换为系统错误代码(-2146233079和0xFFFF = 5385),但不是系统错误代码列表的一部分。
2 个解决方案
#1
1
Rather than using ViewBag, I would suggest adding a Regions property to your Register class, like so:
我建议不要使用ViewBag,而是将Region属性添加到Register类中,如下所示:
public class RegisterModel
{
// ... existing code
public SelectList Regions { get; set; }
}
This requires some updates to your action methods:
这需要对您的操作方法进行一些更新:
// your GET action
public ActionResult Register()
{
var model = new RegisterModel();
model.Regions = new SelectList(_database.Department, "Id", "Name", model.Region);
return View(model);
}
And then, finally, update your view:
然后,最后,更新您的视图:
<li id="region-section">
@Html.LabelFor(m => m.Region)
@Html.DropDownListFor(m => m.Region, Model.Regions, "Select one...")
</li>
This seems to be more consistent than using ViewBag and writing the <select>
element by hand, in my experience.
根据我的经验,这似乎比使用ViewBag和手工编写
If you still are getting odd results from validation, I'd recommend installing Glimpse and checking out the model binding tab, which will show how your posted values are being mapped.
如果您仍然从验证中得到奇怪的结果,我建议安装Glimpse并检查模型绑定选项卡,它将显示您的发布值如何映射。
#2
1
Finnaly I've found answer. The problem was in type of my field (public int Region { get; set; }
). If I don't set anything, mvc trying set null to Region
but int isn't nullable so in controller during debugging I still getting 0
instead null
which was ambiguous.
Finnaly我找到了答案。问题出在我的字段类型中(public int Region {get; set;})。如果我没有设置任何东西,mvc尝试将null设置为Region但int不可为空,因此在调试期间控制器中我仍然得到0而不是null,这是不明确的。
I didn't have [Required]
attribute, but not-nullable type added it automatically (with error name "The X field is required" ... yeah, just like my custom error message in [Range]
attribute).
我没有[Required]属性,但是不可空类型自动添加它(错误名称为“X字段是必需的”...是的,就像我在[Range]属性中的自定义错误消息一样)。
The solution is change:
解决方案是改变:
public int Region { get; set; }
to:
public int? Region { get; set; }
... in viewmodel.
...在viewmodel中。
#1
1
Rather than using ViewBag, I would suggest adding a Regions property to your Register class, like so:
我建议不要使用ViewBag,而是将Region属性添加到Register类中,如下所示:
public class RegisterModel
{
// ... existing code
public SelectList Regions { get; set; }
}
This requires some updates to your action methods:
这需要对您的操作方法进行一些更新:
// your GET action
public ActionResult Register()
{
var model = new RegisterModel();
model.Regions = new SelectList(_database.Department, "Id", "Name", model.Region);
return View(model);
}
And then, finally, update your view:
然后,最后,更新您的视图:
<li id="region-section">
@Html.LabelFor(m => m.Region)
@Html.DropDownListFor(m => m.Region, Model.Regions, "Select one...")
</li>
This seems to be more consistent than using ViewBag and writing the <select>
element by hand, in my experience.
根据我的经验,这似乎比使用ViewBag和手工编写
If you still are getting odd results from validation, I'd recommend installing Glimpse and checking out the model binding tab, which will show how your posted values are being mapped.
如果您仍然从验证中得到奇怪的结果,我建议安装Glimpse并检查模型绑定选项卡,它将显示您的发布值如何映射。
#2
1
Finnaly I've found answer. The problem was in type of my field (public int Region { get; set; }
). If I don't set anything, mvc trying set null to Region
but int isn't nullable so in controller during debugging I still getting 0
instead null
which was ambiguous.
Finnaly我找到了答案。问题出在我的字段类型中(public int Region {get; set;})。如果我没有设置任何东西,mvc尝试将null设置为Region但int不可为空,因此在调试期间控制器中我仍然得到0而不是null,这是不明确的。
I didn't have [Required]
attribute, but not-nullable type added it automatically (with error name "The X field is required" ... yeah, just like my custom error message in [Range]
attribute).
我没有[Required]属性,但是不可空类型自动添加它(错误名称为“X字段是必需的”...是的,就像我在[Range]属性中的自定义错误消息一样)。
The solution is change:
解决方案是改变:
public int Region { get; set; }
to:
public int? Region { get; set; }
... in viewmodel.
...在viewmodel中。