使用 ASP.NET MVC 的待办事项列表






3.11/5 (6投票s)
使用 MVC 创建任务列表。
引言
MVC 发布已经有一段时间了。在本文中,我将通过 ASP.NET MVC 示例出一个用于管理任务(待办事项列表)的应用程序。第一个 Alpha 版本是针对 MVC 的原生功能编译的,以展示其原生功能。未来的版本将包含 jQuery 插件和完整的基于 DAL 的待办事项列表。您可以在此处观看实时演示并下载代码。
待办事项列表(Index 操作)已使用 jquery dataTable
插件更新。感谢Matt Berseth提供的 iTunes 主题用于 GridView
,该主题已被修改并改编用于 dataTable
。屏幕截图如下:

背景
在开始编码之前,请先掌握 MVC 模式,并从ASP.NET下载 Visual Studio 2008 附加组件。您可以从 ASP.NET 网站上的各种视频和教程中获得启发。
之前的版本只使用了原生 MVC,即没有向项目中添加数据层。现在,如果您查看源代码,您会发现代码更加有条理(尽管注释不少!)。但 Controller 甚至不知道自己在做什么,只知道实体(TaskItem
)。这次更新的文章更有价值的是,根据本次发布,使用代码部分几乎全部重写了。
在继续深入之前,让我们先看看解决方案提供了什么!以下是数据项目的一个快速概览。

Using the Code
实体已从 ToDoItem
重命名为 TaskItem
,但 Controller 名称已保留不变,以保持 URL 不变。让我们看看 Model 中实体类的代码。
public partial class TaskItem
{
public int ItemId { get; set; }
public string Title { get; set; }
public int Priority { get; set; }
public DateTime StartDate { get; set; }
public DateTime? DueDate { get; set; }
public int? PercentCompleted { get; set; }
public bool? TrackProgress { get; set; }
public bool? RemindOnDelay { get; set; }
#region object overrides
public override bool Equals(object obj)
{
if (obj is TaskItem)
{
TaskItem item = (TaskItem)obj;
return item.ItemId == this.ItemId;
}
return base.Equals(obj);
}
public override string ToString()
{
return this.Title;
}
public override int GetHashCode()
{
return this.ItemId.GetHashCode();
}
#endregion
}
此 IQuerable 模式实现的功劳归于 Rob Conery。如果您想了解有关 IQueryable
和 todolist 所用模式的更详细教程,Rob 在其博客上发布了关于 MVC Storefront 应用程序的视频教程。您可以在此处观看它们。
对于这个部分类,我们添加了验证逻辑,这样 Controller 端就不再需要进行验证,而是所有验证都在数据层完成。以下代码会检查代码中的任何违规(验证错误)。
public partial class TaskItem
{
public bool IsValid
{
get { return (GetRuleViolations().Count() == 0); }
}
public IEnumerable<RuleViolation> <code>GetRuleViolations()</code>
{
if (string.IsNullOrEmpty(Title))
yield return new RuleViolation("Task title is required.", "Title");
if (Priority <= 0 || Priority > 3)
yield return new RuleViolation("Priority must lie between 1 to 3.", "Priority");
if (DueDate != null && DueDate < StartDate)
yield return new RuleViolation
("Due date must be greater than start date.", "Due Date");
if (PercentCompleted != null && (PercentCompleted <= 0 || PercentCompleted > 100))
yield return new RuleViolation
("Please specify Percentage completed between 1 to 100.",
"Percentage Completed");
yield break;
}
}
GetRuleViolations
函数将帮助我们在数据层为实体操作添加验证检查。感谢 Scott Guthrie 等人撰写了《Professional ASP.NET MVC》(一本很棒的书!)。
正如下面的 InsertTaskItem
函数所示,我们可以非常轻松地检查操作中的验证错误。
/// <summary>
/// Insert the param to database.
/// </summary>
/// <param name="item">TaskItem object to be inserted.</param>
public void InsertTaskItem(TaskItem item)
{
if (!item.IsValid)
throw new ArgumentException();
using (LinqTaskItemDataContext db = new LinqTaskItemDataContext())
{
SqlRepository.TaskItem dbItem = db.TaskItems
.Where(x => x.ItemID == item.ItemId)
.SingleOrDefault();
bool isNew = false;
if (dbItem == null)
{
dbItem = new DevOrigin.ToDoList.Data.SqlRepository.TaskItem();
isNew = true;
}
int itemId = (from taskItem in db.TaskItems
select taskItem.ItemID).Max();
//add the item
dbItem.ItemID = ++itemId;
dbItem.Title = item.Title;
dbItem.Priority = item.Priority;
dbItem.StartDate = item.StartDate;
dbItem.DueDate = item.DueDate;
dbItem.PercentCompleted = item.PercentCompleted;
dbItem.TrackProgress = item.TrackProgress;
dbItem.RemindOnDelay = item.RemindOnDelay;
if (isNew)
db.TaskItems.InsertOnSubmit(dbItem);
db.SubmitChanges();
}
}
现在,Service 层项目仅实现 ITaskItemService
接口。Service 类使用 ITaskItemRepository
方法为其用户提供服务。
正如您在 Controller
方法中看到的,代码已简化为一两行。所有实现都隐藏在数据层中,因此可以轻松更改,而不会影响其上层的层,只要输出保持不变。
哦,我忘了提,如何在 Index controller 中获得漂亮的数据外观?很简单,对吧!我使用了 dataTable
jQuery 插件来实现这一点,然后进行了一些样式设计,使其看起来更漂亮。让我们看看 Index 视图中用于 dataTable 的代码。
<script type="text/javascript" charset="utf-8">
var oTable;
var giRedraw = false;
$(document).ready(function() {
/* Add a click handler to the rows - this could be used as a callback */
$("#taskList tbody").click(function(event) {
$(oTable.fnSettings().aoData).each(function() {
$(this.nTr).removeClass('row_selected');
});
$(event.target.parentNode).addClass('row_selected');
});
oTable = $('#taskList').dataTable({
"bAutoWidth": false,
"bFilter": false
});
});
/* Get the rows which are currently selected */
function fnGetSelected(oTableLocal) {
var aReturn = new Array();
var aTrs = oTableLocal.fnGetNodes();
for (var i = 0; i < aTrs.length; i++) {
if ($(aTrs[i]).hasClass('row_selected')) {
aReturn.push(aTrs[i]);
}
}
return aReturn;
}
</script>
突出显示的代码将实际在 View 中渲染 dataTable
。您还会注意到已注册了一个处理程序,用于在用户单击表格中的任何行时选择该行。还有一个未使用的函数 fnGetSelected
,用于将选定的行返回,它是为将来使用而设计的。您可以在此处获得 dataTable
的完整参考。
当您尝试创建一个新任务时,会收到一个需要输入的项目列表,它们是:标题、优先级、开始日期、截止日期、完成百分比、跟踪进度和显示提醒。
有趣的是,“显示提醒”或 ReminderOnDelay,如果任务延迟达到设定的配置标准,将自动向任务所有者发送电子邮件,虽然尚未实现,但可以轻松实现。ToDoList 将向您展示如何做到这一点。
接下来的计划是为todolist添加增强功能和剩余功能。
关注点
一旦您从网站下载了代码,您会找到 schema.sql 文件,借助该文件,您将能够配置数据库。数据库配置完成后,更新 web.config 文件,以便正确反映连接字符串。
历史
- 0.1.3 (alpha)
- 已更新为 Repository 和 Queryable 模式
- 可在 MSDN、Scott Gu 的博客、Rob Corney 的博客上找到
- v0.1.2 (alpha)
- 为 Detail 操作更新了 jQuery 插件
- v0.1 (alpha)
- 首次发布