2010-04-27 23 views
3

我有一个简单的模型FilesModel更新字符串Description和复选框Archived的几个(已上传)文件的布尔值,并FilesModel有一个验证FilesModelValidator当这些数据被发布时它会运行。这个验证器不过是检查每个文件是否有描述。我知道它运行并根据我的调试到目前为空描述正确返回一个错误。MVC验证错误的时间控制消失给予控制器

但是,当控制器中的Action方法被给予控制时,ModelState与我所期望的不同。说明字段上没有错误,但每个选中的复选框都有一个错误:“'上'的值对存档无效。”

验证此类工作在网站的其他方面工作得很好,所以我确定有一些我可以忽略的东西。任何有关为什么会发生这种情况的建议以及如何解决它?

验证

public FilesModelValidator() 
{ 
    RuleFor(f => f.Files) 
     .Must(AllHaveADescription).WithMessage("Must have a description"); 
} 

public static bool AllHaveADescription(Files files) 
{ 
    // This is run on postback, and returns false when any Description is empty 
    return files.All(f => f.Description != null && f.Description.Length > 0); 
} 

控制器

[HttpPost] 
public virtual ActionResult Update(FilesModel model) 
{ 
    // At this point, ModelState contains an error for each checked checkbox 
    // and no errors for empty descriptions 
    if (ModelState.IsValid) 
    { 
     // Save 
    } 
    return View(model); 
} 
+0

你怎么会有你的验证器连接好?属性属性还是只是一些基于实体的逻辑? – jeriley 2010-04-27 18:40:51

+0

属性。以下是'FilesModel'类的属性:'[Validator(typeof(FilesModelValidator))]' – Aaron 2010-04-27 18:42:03

+0

它可以简单地运行验证两次并删除您的退出错误? (使用自定义模型绑定器可能?)另外,我依稀记得有关注册数据注释(?)的东西..但这会给你所有的问题,并且你正在使用一个以上的权利? – jeriley 2010-04-27 19:48:54

回答

8

事实证明,复选框的事情是整个问题。我在代码的其他地方找到了解决这个问题的一个解决方案,所以我使用了它。它看起来有点不好意思,但它有效。

这个想法是,你需要确保复选框的值是true而不是“on”。所以这样做:

<input type="hidden" id="myCheckbox" value="false" /> 

如果未选中复选框,该复选框价值没有得到:

<input type="checkbox" id="myCheckbox" value="true" /> 

然后用它的值相同的ID false复选框后,立即添加一个隐藏的输入发布回服务器。所以当回发发生时,服务器看到myCheckbox=false这正是我们想要的情况。当复选框时,均为将输入值发布到服务器。但是服务器只使用第一个值(这是复选框本身的值,因为我们把它放在隐藏域之前)。所以服务器看到myCheckbox=true

+1

感谢这个巧妙的解决方法。但是,具有相同id属性的两个元素是无效标记。相反,你应该给他们不同的ID,但添加属性名称=“myCheckbox”这两个元素。这达到了相同的结果,但有效的标记。 – 2012-05-16 10:48:41

+0

@RichardFawcett - 我是有效标记的信徒,所以谢谢你! – Aaron 2012-05-16 17:04:31

+0

轻微挑剔。你根本不需要隐藏的输入。如果你的输入绑定到一个bool,那么它只会导致错误。模型状态也是有效的。您所需要的只是输入具有绑定的值的名称,而'value =“true”'。 Id只用于客户端,与模型绑定无关。 – 2013-03-18 00:41:57

0

我有同样的问题对被链接到一个枚举,在一个下拉的项目。我已经删除了默认值,所以当有人没有选择一些东西时,我得到了一个错误。

所以,说了这么多,我认为你的问题可能有点相关,因为当你的模型正在期待yes/no或者反过来时,活页夹正在寻找真/假。

解决这个问题的两种方法可能是将您的视图更改为True/False,或者,这就是我自己编写自己的ModelBinder,它将从Yes转换为True。

我希望这对你有一些帮助。

+0

我有一个自定义模型绑定器,可以正确解释复选框的值,并且模型上的布尔值被正确设置为true或false。看来,这不是模型绑定,而是一个我没有看到的验证器。 – Aaron 2010-04-28 15:16:06

3

我曾经在视图下,而不是手动创建的复选框:

Html.CheckBox("FieldName")