一、使用ASP.NET MVC创建应用程序
一、使用ASP.NET MVC创建应用程序
这篇文章的通过创建一个asp.net mvc应用程序,展示asp.net mvc是个什么样子,告诉我们如何构建一个简单的asp.net mvc应用程序。
如果我们曾使用过asp和asp.net,那我们对asp.net mvc会感到比较熟悉。从页面外观上看asp.net mvc比较像asp的程序,并且也很像asp.net传统的web应用程序。Asp.net mvc提供了多语言功能和.net框架的完整支持。
在这篇文章中我们来体会asp.net mvc应用程序与asp和asp.net 传统web应用程序的相同与不同之处。
二、工作任务列表程序
为了简单其见,我们在这里构建一个简单的应用程序,这个程序完成了以下功能。
1.显示工作任务列表
2.创建一项新的工作任务
3.标记工作任务是否已完成
同样为了简单其见,这个项目中我们将尽少使用asp.net mvc框架的新特性(如:测试驱动和HTML Helper等)。
三、创建asp.net mvc web应用程序
在VS2008中,单击“文件”-“新建项目”,弹出新建项目对话框。选择ASP.NET MVC Web Application,并在项目名称中写入TaskList点击“确定”
《图1》
在创建asp.net mvc web应用程序时,Visual Studio会弹出提示对话框如下,提示我们是否需要创建一个单元测试项目。在这里我们不想创建单元测试项目,所以我们选择“No”选项,单击“确定”按钮
《图2》
ASP.NET MVC应用程序具有一系列的标准文件夹:Models、Views和Controllers。在解决方案管理器中我们可以看到,我们将向这些文件夹中添加相应的文件来实现我们的应用程序
当我们使用VS2008创建一个新的ASP.NET MVC应用程序时,会生成一个示例程序,我们可以把其中的相关的文件删掉,再来重新添加我们自己的新文件。在这里我们把下在的两个文件删除。
1.Controllers\HomeController.cs
2.Views\Home
四、创建控制器
一般来说在我们构建ASP.NET MVC应用程序的时候,我们是从控制器开始构建的。每个浏览器的请求都会被发送给ASP.NET MVC程序中的一个控制器进行处理。控制器包含响应应用程序请求的一系列程序逻辑。(车延禄)
要新建一个控制器我们需要在解决方案中的Controllers文件夹上右击,选择“添加”->“添加新项”。在弹出的窗口中选择MVC Controller Class模板,并把该控制器文件命名为“HomeController.cs”,单击“添加”按钮。
在这里我们修改HomeController类,代码如下所示,这个控制器中包含四个方法Index(), Create(), CreateNew(), and Complete().每个方法对应一个控制动作。
Listing 1 – HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq; using System.Web;
using System.Web.Mvc;
using TaskList.Models;
namespace TaskList.Controllers
{
public class HomeController : Controller
{
// Display a list of tasks
public ActionResult Index()
{
return View();
}
// Display a form for creating a new task
public ActionResult Create()
{
return View();
}
// Add a new task to the database
public ActionResult CreateNew()
{
return RedirectToAction("Index");
}
// Mark a task as complete
public ActionResult Complete()
{
// database logic
return RedirectToAction("Index");
}
}
}
Index() - 显示所有任务的列表
Create() - 当添加新任务的时候,用来显示form表单。
CreateNew() - 当添加新任务的表单被提交时被调用,这个控制器的动作实际上是把新的任务添加到数据库中去了
Complete() - 通过调用它来把一个任务标记为完成。
当然我们还需要向控制器的动作中添加其它逻辑来使程序按照我们的意图进行工作。
控制器类中对外暴露的公有方法被称为控制器动作。这里需要注意的是:控制器的动作对外暴露。任何人都可以在浏览器的URL地址栏中入相应的路径来调用控制器动作,因此当我们不想让方法被调用的时候,请不要在控制器中添加公有方法。
控制器的动作返回ActionResult型 数据,ActionResult表示动作如何操作。前两个action(Index()和Create())中,返回MVC view,第三个和第四个action直接跳转至其它的action中。
当我们请求Create()控制动作时,返回一个包含新建新任务的表单视图。当提交表单的时候,调用CreateNew()控制动作,CreateNew()控制动作向数据库中添加一个新的任务,并重定向到对Index()控制动作的调用。Index()控制动作返回显示整个任务列表的view视图。最后,当我们把一个任务标记为完成的时候,就会调用Complete()动作,更新数据库。Complete()动作完成更新后重定向到Index()动作上,更新列表的显示。(车延禄)
五、创建视图
视图包含HTML标记和服务器发送至浏览器的内容。视图是ASP.NET MVC应用程序中离页面最近的东西。我们通过创建.aspx文件来创建视图
我们一定要把视图的位置搞清楚。如果我们要为HomeController控制器的Index()动作创建视图,那我们必须把视图放在下面的路径中:
\Views\Home\Index.aspx
如果要为ProductorController控制器的Price()动作创建视图的话,那视图的位置必须放在下面的路径中:
\Views\Product\Price.aspx
一般默认情况下,视图应当与控制器对应的动作具有相同的名称。视图也必须放在与控制器有相同名称的文件夹中。
在解决方案管理器中的Views文件夹上右击,在右键菜单中选择“添加”-“添加新项”,选择MVC View Page模板添加一个新视图。我们创建如下两个视图文件。
\Views\Home\Index.aspx
\Views\Home\Create.aspx
当我们创建完这两个视图的时候,在解决方案管理器中显示如下
《图3》
视图可以包含HTML内容处脚本,Index.aspx视图将用来显示所有任务列表。Index.aspx视图的代码如下
Listing 2 – Index.aspx
<%@ Page Language="C#" AutoEventWireup="false" CodeBehind="Index.aspx.cs" Inherits="TaskList.Views.Home.Index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<div>
<h1>My Tasks</h1>
... displaying all tasks
<a href="/Home/Create">Add new Task</a>
</div>
</body>
</html>
Index.aspx视图当前并没有显示任何任务,这里只是声明正准备显示。我们需要添加脚本在Index.aspx中显示任务列表
在Index.aspx视图中包含一个名子为Add new Task的超链接。这个超链接指向路径“/Home/Create”。当我们点击这个超链接时HomeController控制类的Create()动作会被触发。Create()方法返回创建视图。
Create.aspx视图包含一个新建任务的表单。Create.aspx代码如下:
Listing 3 – Create.aspx
<%@ Page Language="C#" AutoEventWireup="false" CodeBehind="Create.aspx.cs" Inherits="TaskList.Views.Home.Create" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<div>
<h1>Add New Task</h1>
<form method="post" action="/Home/CreateNew">
<label for="description">Task:</label>
<input type="text" name="description" />
<br />
<input type="submit" value="Add Task" />
</form>
</div>
</body>
</html>
需要注意的是这个form表单的Action提交方向为:
/Home/CreateNew.aspx
这个URL指向HomeController控制器的CreateNew()动作。Form表单数据将被提交到这个Action动作中。
六、创建数据库
下面我们创建任务数据库,右击“App_Data”文件夹,在右键菜单中选择“添加”-“添加新项”,选择SqlServer数据模板项,把数据库命名为TaskListDB.mdf,单击“添加”按钮。
在解决方案管理器中,双击“TaskListDB.mdf”,在Tables节点上右击选择“新建表”菜单项,打开数据表设计器,建立如下列:
Id Int 非空
Task Nvarchar(300) 非空
IsCompleted Bit 非空
EntryDate DateTime 非空
第一列Id,有两个属性设置,首先要把Id列设为主键,然后把Id列设为Identity自增长。如图所示。
《图4》
最后保存表。把表命名为Tasks
七、创建模型层
MVC模型包含大部分应用程序和数据库访问逻辑。通常把MVC应用程序的主要的类放在Models文件夹中。把视图层和控制层之外的所有代码,都应放在Models文件夹中。(车延禄)
在这里我们将使用LinQ to SQL与数据库进行交互。个人喜欢LinQ to SQL,这里不是必须使用LinQ to SQL编写ASP.NET MVC程序。只要你喜欢,你可以使用其它的技术,如NHibernate或其它的实体框架与数据库交互
在使用LinQ to SQL前,我们首先要在Models文件夹中创建LinQ to Sql类。右需Models文件夹,“添加”-“添加新项”,选择“LinQ to Sql Classes”模板项,并指定Linq to Sql类为TaskList dbml。单击“添加”按钮。完成这些后,显示OR设计界面。
我们需要创建一个Linq to Sql实体类,来表现我们任务表。从解决方案文件管理器中,把任务管理表拖到OR设计器中,这样就创建了一个名子为Task的Linq to Sql的实例类。点击保存。
《图5》
八、向控制方法中添加数据库逻辑
现在我们有一个数据库,下面我们就可以修改我们的控制器方法,以便我们对数据库的检索和回存操作。HomeController的代码如下。
Listing 4 – HomeController.vb
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TaskList.Models;
namespace TaskList.Controllers
{
public class HomeController : Controller
{
private TaskListDataContext db = new TaskListDataContext();
// Display a list of tasks
public ActionResult Index()
{
var tasks = from t in db.Tasks orderby t.EntryDate descending select t;
return View(tasks.ToList());
}
// Display a form for creating a new task
public ActionResult Create()
{
return View();
}
// Add a new task to the database
public ActionResult CreateNew(string description)
{
// Add the new task to database
Task newTask = new Task();
newTask.Description = description;
newTask.IsCompleted = false;
newTask.EntryDate = DateTime.Now;
db.Tasks.InsertOnSubmit(newTask);
db.SubmitChanges();
return RedirectToAction("Index");
}
// Mark a task as complete
public ActionResult Complete(int Id)
{
// database logic
var tasks = from t in db.Tasks where t.Id == Id select t;
foreach (Task match in tasks)
match.IsCompleted = true;
db.SubmitChanges();
return RedirectToAction("Index");
}
}
}
HomeController类有一个私有的成员变量db ,这个db成员变量是TaskListDataContext类的实例。HomeController类使用db变量操作TaskListDB数据库。
在Index()操制动作中实现了对任务表中所有记录的检索功能,并把任务列表传输给Index视图。
CreateNew()方法中实现了在任务表中插入一条新任务的功能。CreateNew()方法具有一个字符串型的参数description,这个参数接收创建新任务的form表单中的description文本框。ASP.NET MVC框架自动把form表单的字段作为参数传递给控制器的动作。(车延禄)
最后,Complete()方法修改了任务表中的IsComplete列的值。当我们标记一项任务已经结束时,会把这项任务的Id代号传弟给Complete动作,以达到对数据库的修改目的。
九、Index视图层的代码完善
我们还需要做最后一件事情来结束我们的TaskList应用程序。我们需要修改Index 视图,以便显示所有的任务列表,并允许我们把任务标记为结束状态。代码如下:
Listing 5 – Index.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="TaskList.Views.Home.Index" %>
<%@ Import Namespace="TaskList.Models" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Index</title>
</head>
<body>
<div>
<h1>My Tasks</h1>
<ul>
<% foreach (Task task in (IEnumerable)ViewData.Model) { %>
<li>
<% if (task.IsCompleted) {%>
<del>
<%= task.EntryDate.ToShortDateString() %> -- <%=task.Description%>
</del>
<% } else {%>
<a href="/Home/Complete/<%= task.Id.ToString() %>">Complete</a>
<%= task.EntryDate.ToShortDateString() %> -- <%=task.Description%>
<% }%>
</li>
<% } %>
</ul>
<br />
<br />
<a href="/Home/Create">Add new Task</a>
</div>
</body>
</html>
在Index视图中包含了C#的foreach迭代遍历所有的任务列表。任务列表是通过ViewData.Model属性取得的。一般我们都是通过ViewData来从控制层的动作中向视图层传递数据的。
在循环中,我们使用一个条件判断来检查每个任务是否已结束。如果已结束,就把任务显示为一条删除线(<del></del>是删除线的功能)。如果任务没有结果,就把任务显示为一条超链接。
<a href="/Home/Complete/<%= task.Id.ToString() %>">Complete</a>
需要注意的是,这里的URL地址中包含有任务Id。这个任务Id被传给HomeController类的Complete()动作作参数。因此当我们点击相应的Complete超链接时,会正确更新对应的数据库记录
最后Index 视图显示如下的界面
《图6》
十、总结:
这篇文章是为了让我们对ASP.NET MVC应用程序有一个大体的了解,可以从中体会到ASP.NET MVC Web应用程序开发与ASP或ASP.NET非常相似。
在这里我们只是使用了ASP.NET MVC framework的最基本的功能。以后续的文章中我们将对各个主题(如:控制器,控制器动作,视图,视图数据和HTML Helper等)进行深入研究。