我需要在我的asp.net mvc 4项目中使用Range Validator。在视图模型中,我添加了:
[Range(0, int.MaxValue, ErrorMessage = "The Region field is required.")]
public int Region { get; set; }
在控制器中,我通过ModelState.IsValid
检查了它。
问题是ModelState不接受0
作为正确的值 - 这很奇怪,因为我将范围从 0
设置为{{1所以我认为max int
属于集合(如果我记得就像在MVC 5中那样)。我错了还是只是一个错误?任何其他值都正常阅读(0
不接受,-1
可以。)
更新1
(就像你在上面的图片中看到的那样,在我不检查模型是否有效之前,我不会对我的模型做任何事情。)
注册方法:
1001
Full RegisterViewModel类:
[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);
}
注册视图:
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; }
}
更新2
根据@pilotcam的建议,我使用了<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>
功能。在调试模式下,我得到了HResult:ValidateModel()
- 我试图将其转换为系统错误代码(-2146233079
),但不是System Error Codes list的一部分。
答案 0 :(得分:1)
我建议不要使用ViewBag,而是将Region属性添加到Register类中,如下所示:
public class RegisterModel
{
// ... existing code
public SelectList Regions { get; set; }
}
这需要对您的操作方法进行一些更新:
// your GET action
public ActionResult Register()
{
var model = new RegisterModel();
model.Regions = new SelectList(_database.Department, "Id", "Name", model.Region);
return View(model);
}
然后,最后,更新您的观点:
<li id="region-section">
@Html.LabelFor(m => m.Region)
@Html.DropDownListFor(m => m.Region, Model.Regions, "Select one...")
</li>
根据我的经验,这似乎比使用ViewBag和手工编写<select>
元素更加一致。
如果您仍然从验证中得到奇怪的结果,我建议您安装Glimpse并查看model binding tab,这将显示您的发布值的映射方式。
答案 1 :(得分:1)
Finnaly我找到了答案。问题在于我的字段类型(public int Region { get; set; }
)。如果我没有设置任何内容,mvc尝试将null设置为Region
但 int 是不可空的,因此在调试期间控制器中我仍然会0
而不是null
{1}}这是不明确的。
我没有[Required]
属性,但是不可空类型自动添加(错误名称&#34; X字段是必需的&#34; ...是的,就像我的自定义一样[Range]
属性中的错误消息。
解决方案是改变:
public int Region { get; set; }
为:
public int? Region { get; set; }
...在viewmodel中。