前一陣子完成了「ASP.NET MVC - CheckBoxList 與 ValidationMessage (ASP.NET MVC 5 with Bootstrap3)」與「ASP.NET MVC - CheckBoxList 與 ValidationMessage (ASP.NET MVC 4 without Bootstrap)」這兩篇有關於 CheckBoxList 與 ASP.NET MVC ValidationMessage 的應用,但這兩篇文章與之前有關 CheckBoxList 的文章都只有展示 CheckBoxList 的功能,並沒有實際針對在資料的 CRUD(Create, Read, Update, Delete)操作上去怎麼使用,所以這一篇文章就來說明怎麼在資料的 CRUD 操作去使用 CheckBoxList。
開發環境:Visual Studio 2013 Update 2 , LocalDB , ASP.NET MVC 5 , Entity Framework 6.1.0
建立一個 ASP.NET MVC 5 專案
Foobar
這是我們要進行 CRUD 處理的 Table,而其中 Categories 欄位所要儲存的是 Northwind 的 Category 的 ID 編號,多個 Category ID 將會用「,」逗號分隔,
ViewModel
這邊建立 View 與 Controller 所使用的 ViewModel 類別,將原本 EF 所建立 Foobar 類別再另外建立 Partial Class 以及 MetadataType Class,
using System;using System.ComponentModel.DataAnnotations;namespace WebApplication1.Models{ [MetadataType(typeof(FoobarMetadata))]public partial class Foobar
{public class FoobarMetadata
{ [Display(Name = "編號")] [Required(ErrorMessage = "為必要欄位")] public Guid ID { get; set; } [Display(Name = "名稱")][Required]
[StringLength(100, ErrorMessage = "請輸入名稱")]public string Name { get; set; }
[Display(Name = "分類")] [Required(ErrorMessage = "請至少選擇一個分類")]public string Categories { get; set; }
[Display(Name = "建立日期")] [Required(ErrorMessage = "為必要欄位")] public DateTime CreateDate { get; set; } [Display(Name = "更新日期")] [Required(ErrorMessage = "為必要欄位")] public DateTime UpdateDate { get; set; }}
public string SelectedCategories { get; set; }
}
}
Service
再來建立 FoobarService,
using System;using System.Linq;using WebApplication1.Infrastructure.Repository;using WebApplication1.Models;namespace WebApplication1.Infrastructure.Services{public class FoobarService
{private IRepository<Foobar> _Repository = new DataRepository<Foobar>();
public void Create(Foobar instance)
{if(instance == null)
{throw new ArgumentNullException("instance", "null");
}
instance.ID = Guid.NewGuid();
instance.CreateDate = DateTime.Now;
instance.UpdateDate = DateTime.Now;
this._Repository.Add(instance); this._Repository.SaveChanges();}
public void Delete(Guid id)
{ var instance = this.GetOne(id);if (instance == null)
{throw new InvalidOperationException("not found");
}
this._Repository.Delete(instance); this._Repository.SaveChanges();}
public void Update(Foobar instance)
{if (instance == null)
{throw new ArgumentNullException("instance", "null");
}
instance.UpdateDate = DateTime.Now;
this._Repository.Update(instance); this._Repository.SaveChanges();}
public bool IsExists(Guid id)
{return this._Repository.IsExists(x => x.ID == id);
}
public Foobar GetOne(Guid id) {return this._Repository.FirstOrDefault(x => x.ID == id);
}
public IQueryable<Foobar> GetAll() {return this._Repository.FindAll().OrderByDescending(x => x.CreateDate);
}
}
}
FoobarController
using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Web.Mvc;using WebApplication1.Infrastructure.Services;using WebApplication1.Models;namespace WebApplication1.Controllers{public class FoobarsController : Controller
{private FoobarService foobarService = new FoobarService();
private CategoryService categoryService = new CategoryService();
private List<SelectListItem> CategorySelectListItems(string selected = "")
{ var categories = this.categoryService.GetAll(); var items = new List<SelectListItem>(); var selectedCategories = string.IsNullOrWhiteSpace(selected) ? null : selected.Split(',');foreach (var c in categories)
{ items.Add(item: new SelectListItem() {Value = c.CategoryID.ToString(),
Text = c.CategoryName,
Selected = selectedCategories == null ? false: selectedCategories.Contains(c.CategoryID.ToString())
});
}
return items;}
public ActionResult Index() { var foobars = this.foobarService.GetAll(); var categories = this.CategorySelectListItems(); var result = new List<Foobar>();foreach ( var item in foobars )
{ var selectedList = item.Categories.Split(',').ToList(); item.SelectedCategories = string.IsNullOrWhiteSpace(item.Categories) ? "" : string.Join( ",",categories.Where(x => selectedList.Contains(x.Value)).Select(x => x.Text));
result.Add(item);
}
return View(result.ToList());}
public ActionResult Details(Guid? id) {if (id == null)
{return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Foobar foobar = this.foobarService.GetOne(id.Value);if (foobar == null)
{ return HttpNotFound();}
var items = this.CategorySelectListItems(foobar.Categories); foobar.SelectedCategories = string.IsNullOrWhiteSpace(foobar.Categories) ? "": string.Join(",", items.Where(x => x.Selected).Select(x => x.Text));
return View(foobar);}
public ActionResult Create() { var items = this.CategorySelectListItems();ViewBag.CategoryItems = items;
return View();}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(string name, string[] categories)
{ var foobar = new Foobar {Name = name,
Categories = string.Join(",", categories)
};
if (ModelState.IsValid) { this.foobarService.Create(foobar);return RedirectToAction("Index");
}
var items = this.CategorySelectListItems();ViewBag.CategoryItems = items;
return View(foobar);}
public ActionResult Edit(Guid? id) {if (id == null)
{return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Foobar foobar = this.foobarService.GetOne(id.Value);if (foobar == null)
{ return HttpNotFound();}
var items = this.CategorySelectListItems(foobar.Categories);ViewBag.CategoryItems = items;
return View(foobar);}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Guid id, string name, string[] categories)
{ var foobar = this.foobarService.GetOne(id);if (foobar == null)
{return RedirectToAction("Index");
}
if (ModelState.IsValid) {foobar.Name = name;
foobar.Categories = string.Join(",", categories);
this.foobarService.Update(foobar);return RedirectToAction("Index");
}
var items = this.CategorySelectListItems();ViewBag.CategoryItems = items;
return View(foobar);}
public ActionResult Delete(Guid? id) {if (id == null)
{return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Foobar foobar = this.foobarService.GetOne(id.Value);if (foobar == null)
{ return HttpNotFound();}
var items = this.CategorySelectListItems(foobar.Categories); foobar.SelectedCategories = string.IsNullOrWhiteSpace(foobar.Categories) ? "": string.Join(",", items.Where(x => x.Selected).Select(x => x.Text));
return View(foobar);}
[HttpPost, ActionName("Delete")][ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(Guid id) {bool isExists = this.foobarService.IsExists(id);
if (!isExists) {return RedirectToAction("Index");
}
this.foobarService.Delete(id);return RedirectToAction("Index");
}
}
}
Views
在 Create 與 Edit 的 View 原始碼裡,要特別注意的是最底下的Javascript Code,可千萬別忘了。
Create.cshtml
@using WebApplication1.Infrastructure.Enums@model WebApplication1.Models.Foobar
@{ ViewBag.Title = "Create";}
<h2>Create</h2>
@using (Html.BeginForm()){@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Foobar</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Categories, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@*@Html.EditorFor(model => model.Categories, new { htmlAttributes = new { @class = "form-control" } })*@
@*@Html.ValidationMessageFor(model => model.Categories, "", new { @class = "text-danger" })*@
@Html.EditorFor(model => model.Categories,
"CheckBoxList", new { TagName = "Categories",CheckBoxItems = ViewBag.CategoryItems,
Position = Position.Vertical,
Numbers = 3
})
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts { @Scripts.Render("~/bundles/jqueryval") <script type="text/javascript"> $(function () {$('input[name="Categories"]').rules('add', {
messages: { required: "請至少選擇一個分類"}
});
});
</script>
}
Edit.cshtml
@using WebApplication1.Infrastructure.Enums@model WebApplication1.Models.Foobar
@{ ViewBag.Title = "Edit";}
<h2>Edit</h2>
@using (Html.BeginForm()){@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Foobar</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.ID)
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Categories, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@*@Html.EditorFor(model => model.Categories, new { htmlAttributes = new { @class = "form-control" } })*@
@*@Html.ValidationMessageFor(model => model.Categories, "", new { @class = "text-danger" })*@
@Html.EditorFor(model => model.Categories,
"CheckBoxList", new { TagName = "Categories",CheckBoxItems = ViewBag.CategoryItems,
Position = Position.Vertical,
Numbers = 3
})
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts { @Scripts.Render("~/bundles/jqueryval") <script type="text/javascript"> $(function () {$('input[name="Categories"]').rules('add', {
messages: { required: "請至少選擇一個分類"}
});
});
</script>
}
執行結果
Index (List)
Create
Details
Edit
Delete
文章內容的程式範例已經上傳到 GitHub,想要查看程式細節或是下載範例程式的朋友請自行前往。
GitHub Repository
以上
沒有留言:
張貼留言