2015-11-14 39 views
-1

我需要在我的asp.net mvc 4项目中使用Range Validator。在视图模型我说:MVC 4范围验证器不接受最小值

[Range(0, int.MaxValue, ErrorMessage = "The Region field is required.")] 
public int Region { get; set; } 

并在控制器我通过ModelState.IsValid检查它。

问题是ModelState中不接受0作为正常价值 - 这是奇怪的,因为我从0max int设置范围,所以我想0属于集合(像MVC 5,如果我记得)。我错了还是只是一个错误?任何其他值正在正确读取(-1不接受并且1001没问题)。

更新1

Debug 1 enter image description here

(就像你看到的上面的照片我不和我的模型东西之前我没有检查,如果模型是有效的)。

注册方法:

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

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

注册视图:

<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

根据@pilotcam的建议,我用ValidateModel()函数。在调试模式下,我得到了HResult:-2146233079 - 我试图将它转换为系统错误代码(),但不是System Error Codes list的一部分。

+0

这不应该发生。你调试过,没有看到其他问题? –

+0

@ArghyaC:是的,我是调试和ModelState.IsValid只有在区域键false。我的RegisterViewModel的Rest键是真的。 –

+1

在'RangeAttribute'中,包含最小值和最大值。我刚刚检查了源代码。他们很好。看看别的东西是否正在改变这些值,或者是否还有其他的错误。 –

回答

1

Finnaly我找到了答案。问题出在我的领域(public int Region { get; set; })。如果我没有设置任何东西,mvc尝试将null设置为Region,但是int在控制器调试过程中不能为空,所以在控制器中我仍然得到0而不是null这是不明确的。我没有[Required]属性,但不是可以为空的类型自动添加它(错误名称“X字段是必需的”...是的,就像我的自定义错误消息在[Range]属性)。

解决的办法是改变:

public int Region { get; set; } 

到:

public int? Region { get; set; } 

...在视图模型。

+1

谢谢,我知道你在你最初的问题上有负面的观点,但是当模型没有被填充时,null验证为false并不明显,除了回想起来。 –

1

而不是使用ViewBag,我建议增加一个区域属性您注册类,如下所示:

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> 

这似乎比使用View更一致根据我的经验,手工编写并编写<select>元素。

如果仍然都可以从验证奇怪的结果,我建议你安装Glimpse,并检查出model binding tab,它会显示您的公布值是如何被映射。