MVC Checkbox
单个Checkbox
针对single checkbox使用方法和textbox等并没有太大区别, 代码如下:
View:
<%= Html.CheckBoxFor(model => model.IsNeverExpired)%>
HTML生成:
<input id="IsNeverExpired" name="IsNeverExpired" type="checkbox" value="true" /> <input name="IsNeverExpired" type="hidden" value="false" />
Controller:
//创建 public override JsonResult Create(Credential model) { } //编辑 public override JsonResult Edit(string id, FormCollection formValues) { Credential model = repository.GetByID(Convert.ToInt32(id)); UpdateModel(model); }
上面生成的HTML有点奇怪, 为什么它会生成两个控件呢?
因为如果只生成一个input, 系统无法区分"没有选中checkbox" 和 "checkbox没有生成".
那又是为什么只生成一个input就无法区分呢?
原来当一个form中包含checkbox时,如果没有给它赋值(选中), 在服务器端Request.Form中得到的值是NULL
据说是标准的browser behaviour.
参见:http://forums.asp.net/t/1425806.aspx/1/10
多个Checkbox
当对象之间是多对多的关系时, 在数据库中一般是通过建立一个中间表来映射, 如一个证件有多个专业(或一篇文章属于多个Categorie)
此时CheckBox组就派上用场了. 由于并没有类似Html.CheckBoxListFor这样的方法, 我是通过如下方法实现的.
View:
<% foreach (var item in (MultiSelectList)ViewData["list"]) {%> <input type="checkbox" name="ProfessionalIDs" value="<%=item.Value%>" id="Professional<%=item.Value%>" <%=item.Selected ? "checked=\"checked\"" : String.Empty%> /> <label for="Professional<%=item.Value%>"><%=item.Text%></label> <%} %>
Controller:
View Code
public override ActionResult Create() { Credential model = new Credential(); model.InitProfessionalList(); ViewData["list"] = new MultiSelectList(model.Professionals.Items, "TypeID", "Name", null); return View(model); } [AcceptVerbs(HttpVerbs.Post)] public override JsonResult Create(Credential model) { if (model.ProfessionalIDs == null) { model.CredentialProfessional = new System.Data.Linq.EntitySet<CredentialProfessional>(); } else { foreach (int professionalID in model.ProfessionalIDs) { model.CredentialProfessional.Add(new CredentialProfessional() { CredentialID = model.CredentialID, ProfessionalID = professionalID }); } } ... } [AcceptVerbs(HttpVerbs.Post)] public override JsonResult Edit(string id, FormCollection formValues) { repository.Edit(model, formValues["ProfessionalIDs"]); ... }
Repository:
View Code
public StatusEnum Add(TEntity entity) { db.GetTable<TEntity>().InsertOnSubmit(entity); db.SubmitChanges(); return StatusEnum.Success; } public StatusEnum Edit(Credential model, string professional) { List<CredentialProfessional> newSelect = new List<CredentialProfessional>(); if (!string.IsNullOrEmpty(professional)) { string[] professionalArray = professional.Split(','); foreach (string professionalID in professionalArray) //新选择的项保存到集合中 { newSelect.Add(new CredentialProfessional() { CredentialID = model.CredentialID, ProfessionalID = Convert.ToInt32(professionalID) }); } } model.CredentialProfessional.Except(newSelect).ToList().ForEach(n => db.CredentialProfessional.DeleteOnSubmit(n)); newSelect.Except(model.CredentialProfessional).ToList().ForEach(n => db.CredentialProfessional.InsertOnSubmit(n)); db.SubmitChanges(); return StatusEnum.Success; }
说明: CredentialProfessional就是中间表, 须以其2个外健做为联合主健.
签名:删除冗余的代码最开心,找不到删除的代码最痛苦!