摘要
本文首先一步一步完成
Demo
的第一个页面
——
首页。然后根据实现过程,说明一下其中用到的与
ASP.NET MVC
相关的概念与原理。
让第一个页面跑起来
现在,我们来实现公告系统中的第一个页面
——
首页。它非常简单,只包括所有公告分类的列表,并且每个列表项是一个超链接。其中分类数据是用我们的
Mock
组件得到的。实现后界面如下:
在开始之前,我们要删几个东西。因为默认情况下建立一个
MVC
项目时里面包含了几个示例页面,我们要做的就是:
1.
将
Controllers
文件夹下所有文件删除。
2.
将
Views
文件夹下除了
Shared
文件夹和
Web.config
外的所有文件删除,然后将
Shared
文件夹里面的文件删除。
完成以上几步后,就可以开始实现第一个页面了。
实现控制器
在
Controllers
文件夹下新建一个文件,类型选择“
MVC Controller Class
”,名字命名为
HomeController.cs
。这就是一个控制器类。然后我们为它编码,具体代码如下:
HomeController.cs:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Mvc.Ajax;
- using MVCDemo.Models;
- using MVCDemo.Models.Interfaces;
- using MVCDemo.Models.Entities;
- namespace MVCDemo.Controllers
- {
- public class HomeController : Controller
- {
- public ActionResult Index()
- {
- ICategoryService cServ = ServiceBuilder.BuildCategoryService();
- ViewData[ "Categories" ] = cServ.GetAll();
- return View( "Index" );
- }
- }
- }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Mvc.Ajax; using MVCDemo.Models; using MVCDemo.Models.Interfaces; using MVCDemo.Models.Entities; namespace MVCDemo.Controllers { public class HomeController : Controller { public ActionResult Index() { ICategoryService cServ = ServiceBuilder.BuildCategoryService(); ViewData["Categories"] = cServ.GetAll(); return View("Index"); } } }
直观看来,这个类不是很复杂。它首先继承了
Controller
类。
Controller
类是
ASP.NET MVC
框架中提供的一个控制器积累,所有我们自定义的控制器类都要继承此基类。然后这个类中有一个
Index
方法,返回值类型是
ActionResult
。
这里对其中涉及到的概念简单解释一下。首先,控制器类可以说是
ASP.NET MVC
的核心类,因为它将处理一切请求,并处理所有页面转发等表示逻辑,这也是使用了
ASP.NET MVC
后与传统
ASP.NET
应用最大的差别。在传统模式下,一个用户请求的
url
将对应一个
aspx
文件,而在
ASP.NET MVC
下,一个用户请求对应某个控制器类中的一个方法,而这个方法,就叫做一个
Action
。至于如何对应的,则是通过对
url
的解析。
例如,在传统情况下,
http://www.my400800.cn/index.aspx
表示请求网站根目录下的
Default.aspx
文件。而现在,
url
可能变成了这种样子:
http://blog.my400800.cn/北京400电话申请/1
。这个意思就是,请求名叫
HomeController
控制器类下的
Index
方法。一般地,默认情况下,请求
url
的格式为
http://localhost/{ControllerName}/{ActionName
}
。其中
{ControllerName}
是控制器类名“
Controller
”前的部分,
{ActionName}
就是方法名。
当然,这种映射规则是可以更改的,而且请求
Action
时也可以传递参数,但这些都是后话,以后再慢慢讨论。
下面再深入
Index
方法,看看这个
Action
都做了什么。它首先调用了业务逻辑组件(当然,是
Mock
的),然后将
GetAll
返回的公告分类数据赋予
ViewData["Category"]
,最后调用
View()
方法返回一个
ActionResult
。
ViewData
是什么呢?你可以把他理解成一个关联数组,它保存需要传给视图的数据。而
View
是
Controller
类的一个方法,它返回一个
ActionResult
实例。这样说可能有点抽象,其实直观就是将某个视图(一般就是一个
aspx
文件)呈现到浏览器中。那么如何知道呈现哪一个视图呢?默认情况下,
View
方法会到网站的
Views
文件夹下的与控制器类同名的文件夹下寻找与
Action
方法同名的视图。例如,
HomeController
的
Index
方法就会寻找
Views/Home/Index.aspx
,如果找不到,就会到
Shared
下寻找,再找不到就报错了。当然,你也可以给
View
方法传递一个字符串参数,表示视图名称。
实现视图
上文说到,当请求
http://localhost/Home/Index
时,
HomeController
的
Index
方法会被调用,而
Index
方法最后要呈现
Views/Home/Index.aspx
视图,所以,我们要在
Views
文件夹下建立一个
Home
文件夹,然后再新建一个
Index.aspx
视图。如果您使用的是
VS2008 SP1
,那么建立视图非常方便,只要在
Home
文件夹下右键单击,选
Add--->View
,然后指定视图名就可以了。如果不是
SP1
的,就新建一个
Item
,类型选择“
MVC View Page
”。建立好的视图其实就是一个
aspx
页面,但是其继承了
View
。这也是一个基类,所有视图需要继承它。
下面给出
Index.aspx
的代码:
Index.aspx:
- <%@ Page Language= "C#" AutoEventWireup= "true" CodeBehind= "Index.aspx.cs" Inherits= "MVCDemo.Views.Home.Index" %>
- <%@ Import Namespace= "MVCDemo.Models.Entities" %>
- <!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>
- <% List<CategoryInfo> categories=ViewData[ "Categories" ] as List<CategoryInfo>; %>
- <div>
- <h1><A href= "http://www.my400800.cn" >400电话</A>
- MVC公告发布系统</h1>
- <ul>
- <% foreach (CategoryInfo c in categories)
- {
- %>
- <li><%= Html.ActionLink(c.Name, "List/" + c.ID, "Announce" ) %></li>
- <% } %>
- </ul>
- </div>
- </body>
- </html>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MVCDemo.Views.Home.Index" %> <%@ Import Namespace="MVCDemo.Models.Entities" %> <!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> <% List<CategoryInfo> categories=ViewData["Categories"] as List<CategoryInfo>; %> <div> <h1> 400电话 MVC公告发布系统</h1> <ul> <% foreach (CategoryInfo c in categories) { %> <li><%= Html.ActionLink(c.Name, "List/" + c.ID, "Announce") %></li> <% } %> </ul> </div> </body> </html>
大约分析一下。刚才说过,
Index
这个
Action
最后呈现这个
aspx
作为视图,而且
ViewData
中包含了要给视图传递的数据。在那里,我们将所有公告类别数据放在
ViewData["Categories"]
中。这里可以看到,我们将这些数据取出,并用来呈现页面。至于那个
Html.Action
,这里先不细说。你只要知道,这个方法可以生成一个链接,其中第一个参数是链接文字,第二个是要链接到的
url
的
Action
名,第三个是要链接到的
url
的控制器名。关于这些,我们以后细细讨论。
运行这个例子,并将请求
url
定位到
Home/Index
,就可以看到运行效果。
你可能会发现,不需要指定
Home/Index
,在输入根目录后就直接呈现了这个页面。其实这是因为在默认的路由配置里,
Home
和
Index
是默认的控制器名和
Action
名。以后我们将会讨论路由问题。
小结
通过上面的过程,我们第一个
ASP.NET MVC
页面已经能呈现出来了。而且不单纯只是一个页面,其中还呈现了业务逻辑组件返回的数据。
也许,您对其中许多地方还有困惑。不要着急,在下一篇中,我们做这个系统的步伐先