ASP.NET MVC自动生成的手脚架很方便,但是在我们实际的工作中,那仅仅是开始而已。下面我们以一个实例来讨论ASP.NET MVC的排序、搜索和分页,最后我们完成一个简单的多对多数据库。
打开VS2015,创建一个MVC项目,取名为PersonnelTask,新建一个Model-Personnels:
public class Personnels
{
public int PersonnelsId { get; set; }
[Required(ErrorMessage = "请输入名称。")]
[StringLength(160, MinimumLength = 4)]
[Display(Name = "名称")]
public string Name { get; set; }
[Required(ErrorMessage = "请输入薪水。")]
[Display(Name = "薪水")]
public decimal Pay { get; set; }
[Required(ErrorMessage = "请输入入职时间。")]
[Display(Name = "入职时间")]
public DateTime Date { get; set; }
}
接着,我们新建一个控制器:包含视图的MVC 5控制器,具体设计如下图:
完成手脚架后,我们开始填入种子数据
1.在项目里面的Models文件夹,新建一个种子类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace PersonnelTask.Models
{
public class DbInitializer:System.Data.Entity.DropCreateDatabaseAlways<PersonnelTaskContext>
{
protected override void Seed(PersonnelTaskContext context)
{
context.Personnels.Add(new Personnels { Name = "张三", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "李四", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "张马子", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "阳明", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "张伟", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "徐可", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "王丽", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "玛丽", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "麦克", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "潭门", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "于谦", Pay = 2000, Date = DateTime.Now });
context.Personnels.Add(new Personnels { Name = "郭德", Pay = 2000, Date = DateTime.Now });
base.Seed(context);
}
}
}
2.打开Global.asax.cs,加入下面打代码:
protected void Application_Start()
{
Database.SetInitializer(new DbInitializer());
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
下面我们来演示一下排序。
数据库排序的功能是很重要的,在本例中,我希望可以通过点击“薪水”或者“入职时间”,重新按照“薪水”或者“入职时间”的升序或者降序来排列我们的数据。
思路:我们在index控制器里面增加一个参数sortOrder,用它来接收需要排序的值 public ActionResult Index(string sortOrder)
通过这些值的不同,我们的数据排序就是根据这些值进行排列的。下面是源代码:
public ActionResult Index(string sortOrder)
{
var ps = from s in db.Personnels select s;
ViewBag.PaySortPam = sortOrder == "pay" ? "pay_desc" : "pay";
ViewBag.DateSort = sortOrder == "date" ? "date_desc" : "date";
switch (sortOrder)
{
case "pay_desc":
ps = ps.OrderByDescending(s => s.Pay);
break;
case "pay":
ps=ps.OrderBy(s => s.Pay);
break;
case "date_desc":
ps = ps.OrderByDescending(s => s.Date);
break;
case "date":
ps=ps.OrderBy(s => s.Date);
break;
default:
ps = ps.OrderByDescending(s => s.PersonnelsId);
break;
}
return View(ps.ToList());
}
从上面的代码可以看出,我们总共列出了5种数据排列方式,默认排列方式、按薪水高低两种排列方式、按入职日期早晚两种排列方式。
在视图里面我们也要做一下修改:
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.ActionLink("薪水", "Index", new { sortOrder = ViewBag.PaySortPam })
</th>
<th>
@Html.ActionLink("入职日期", "Index", new { sortOrder = ViewBag.DateSort })
</th>
<th></th>
</tr>
这样就好了,完成了我们的排序功能。
下面,我们下面来做一个搜索名称的搜索框,打开视图,加入下面的代码
@using (Html.BeginForm())
{
<p>
Find By Name:
@Html.TextBox("SearchString") <input type="submit" value="Search" />
</p>
}
看起来还不错,再到控制器里面修改代码:
public ActionResult Index(string sortOrder,string searchString)
{
var ps = from s in db.Personnels select s;
if (!string.IsNullOrEmpty(searchString)) {
ps = ps.Where(s => s.Name.ToUpper().Contains(searchString.ToUpper()));
}
...省掉重复代码
}
不错,这个功能也能用了。
分页需要到NuGet下载PagedList.Mvc 包,安装完成以后有提示
在控制器中增加一句:using PagedList;
由于增加了分页包,代码修改量比较大,下面将全部代码奉上。首先修改自控制器:
public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.PaySortPam = sortOrder == "pay" ? "pay_desc" : "pay";
ViewBag.DateSort = sortOrder == "date" ? "date_desc" : "date";
if (searchString != null) { page = 1; } else { searchString = currentFilter; }
ViewBag.CurrentFilter = searchString;
var ps = from s in db.Personnels select s;
if (!string.IsNullOrEmpty(searchString))
{
ps = ps.Where(s => s.Name.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "pay_desc":
ps = ps.OrderByDescending(s => s.Pay);
break;
case "pay":
ps = ps.OrderBy(s => s.Pay);
break;
case "date_desc":
ps = ps.OrderByDescending(s => s.Date);
break;
case "date":
ps = ps.OrderBy(s => s.Date);
break;
default:
ps = ps.OrderByDescending(s => s.PersonnelsId);
break;
}
int pageSize = 3;
int pageNumber = (page ?? 1);
return View(ps.ToPagedList(pageNumber, pageSize));
}
视图页全部代码:
@using PagedList.Mvc;
@model PagedList.IPagedList<PersonnelTask.Models.Personnels >
<link href = "~/Content/PagedList.css" type = "text/css" rel = "stylesheet" />
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm("Index","Personnels", FormMethod.Get))
{ <p>
Find By Name:
@Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
<table class="table">
<tr>
<th>
名称
</th>
<th>
@Html.ActionLink("薪水", "Index", new { sortOrder = ViewBag.PaySortPam, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.ActionLink("入职日期", "Index", new { sortOrder = ViewBag.DateSort, currentFilter = ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Pay)
</td>
<td>
@Html.DisplayFor(modelItem => item.Date)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.PersonnelsId }) |
@Html.ActionLink("Details", "Details", new { id = item.PersonnelsId }) |
@Html.ActionLink("Delete", "Delete", new { id = item.PersonnelsId })
</td>
</tr>
}
</table>
<br />
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
@Html.PagedListPager(Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
测试通过。
好,现在已经基本实现了员工表的基本功能,现在,我们来新建一个Tasks任务表
public class Tasks
{
public int TasksId { get; set; }
[Required(ErrorMessage = "请输入名称。")]
[StringLength(160, MinimumLength = 4)]
[Display(Name = "名称")]
public string Name { get; set; }
public virtual ICollection<Taskspersonnel> Taskspersonnels { get; set; }
}
同时修改一下Personnels类:
public class Personnels
{
public int PersonnelsId { get; set; }
[Required(ErrorMessage = "请输入名称。")]
[StringLength(160, MinimumLength = 1)]
[Display(Name = "名称")]
public string Name { get; set; }
[Required(ErrorMessage = "请输入薪水。")]
[Display(Name = "薪水")]
public decimal Pay { get; set; }
[Display(Name = "入职时间")]
public DateTime Date { get; set; }
public virtual ICollection<Taskspersonnel> Taskspersonnels { get; set; }
}
现在有员工、有任务,那么要将员工和任务联系起来,就是一个员工任务列表,是一个多对多的数据库关系。一个员工执行多项任务,一个任务由多个员工执行。如果没有Tasksdate(任务执行时间)的话,这个类可以不用建立。因为它只有两个外键。
public class Taskspersonnel
{
public int TaskspersonnelId { get; set; }
public int PersonnelsId { get; set; }
public int TasksId { get; set; }
public DateTime Tasksdate { get; set; }
public virtual Personnels personnels { get; set; }
public virtual Tasks tasks { get; set; }
}
运行生成解决方案后,对这两个实体类新建控制器。
先对Tasks填入一些测试数据。
然后运行/Taskspersonnels/Create:
因为最后一个日期格式,如果这样直接让用户输入,有可能会输错、报错。所以我们还是找一个日历包给它好了。
安装JQuery.UI.Widgets.Datepicker,我在安装过程中发生了BUG,所以我直接去JQuery.UI官网上下载。
只要将jquery-ui.min.js和jquery-ui.css引入项目里面,对日期项的TEXT做一下修改
@Html.EditorFor(model => model.Tasksdate, new { htmlAttributes = new { @class = "form-control datepick"} })
最后,在该视图中加入JQuery代码,完成!
<script>
$(function () {
$(".datepick").datepicker();
});
</script>
谢谢大家。转帖的时候请把凉风有兴或者AlexZeng.net进行署名。本文版权声明:自由转载-非商用-以非衍生-保持署名(创意共享3.0许可证)