正如您所发现的,您只能使用CheckBoxFor()
绑定到bool
属性。它有点不清楚,为什么你有2楼这一观点的模型时,你可以通过只使用
public class Presenter
{
[Required(ErrorMessage = "You must select at least one site.")]
[Display(Name = "All site to have access too")]
public int[] Sites { get; set;
public IEnumerable<Site> AvailableSites { get; set; }
}
一种选择,你可以考虑把它简化(基于上述模型和假设的Site
类型包含属性int ID
和string Name
)
更改视图以手动生成<input type="checkbox" />
元件
@foreach(var site in Model.AvailableSites)
{
// assumes your using Razor v2 or higher
bool isSelected = Model.Sites.Contains(s.ID);
<label>
<input type="checkbox" name="Sites" value="@site.ID" checked = @isSelected />
<span>@s.Name</span>
</label>
}
@Html.ValidationMessageFor(m => m.Sites)
注@Html.LabelFor(m => m.Sites)
是不合适的。 A <label>
是用于将焦点设置到其关联的表单控件的可访问性元素,并且您没有Sites
的表单控件。您可以使用
一个更好的选择(和MVC方式)是创建一个视图模型代表您可以在视图
public class SiteVM
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
,并在你的GET方法想要的东西,基于所有可用返回List<SiteVM>
站点(例如
List<SiteVM> model = db.Sites.Select(x => new SiteVM() { ID = x.ID, Name = x.Name };
return View(model);
,并在视图中使用一个for
循环的EditorTemplate
(参照this answer更多细节)来生成视图
@model List<SiteVM>
....
@using (Html.BeginForm())
{
for(int i = 0; i < Model.Count; i++)
{
@Html.HiddenFor(m => m[i].ID)
@Html.HiddenFor(m => m[i].Name)
<label>
@Html.CheckBoxFor(m => m[i].IsSelected)
<span>@Model[i].Name</span>
</label>
@Html.ValidationMessage("Sites")
}
....
}
,然后在POST方法
[HttpPost]
public ActionResult Edit(List<SiteVM> model)
{
if (!model.Any(x => x.IsSelected))
{
ModelState.AddModelError("Sites", "Please select at least one site");
}
if (!ModelState.IsValid)
{
return View(model);
}
...
}
在这两种情况下,你不能使用jquery.validate.unobtrusive
,因为你没有(也不能)创建这是一个集合的属性表单控件的客户端验证。但是,您可以编写自己的脚本,以显示确认消息并取消默认的提交,例如(假设你使用@Html.ValidationMessageFor(m => m.Sites, "", new { id = "sitevalidation" })
)
var sitevalidation = $('#sitevalidation');
$('form').submit(function() {
var isValid = $('input[type="checkbox"]:checked').length > 0;
if (!isValid) {
sitevalidation.text('Please select at least one site');
return false; // cancel the submit
}
}
$('input[type="checkbox"]').click(function() {
var isValid = $('input[type="checkbox"]:checked').length > 0;
if (isValid) {
sitevalidation.text(''); // remove validation message
}
}
使用编辑器模板。看看[如何知道从HttpPost创建操作方法中选择的复选框?](http://stackoverflow.com/questions/38961222/how-to-know-the-selected-checkboxes-from-within-the -httppost-create-action-metho) – Shyju
你是说我不能做双向绑定,我必须手动检查选定的值吗? – Jaylen