3.3 第一个ASP.NETMVC程序

本节我们通过新建一个ASP.NET MVC程序来了解ASP.NET MVC项目框架的一些基本概念和执行过程,让大家先对ASP.NET MVC有一个基本的认识。

3.3.1创建项目

开发流程:

● 新建一个MVC项目。

● 新建Controller。

●创建Action。

● 根据Action创建View。

● 在Action获取数据并生产ActionResult传递给View。

● View是显示数据的模板。

● URL请求→Controller.Action处理→View响应。

首先打开VS,选择“文件→新建项目FirstMVCApp”,如图3-6所示。

图3-6

单击“确定”后,会出现如图3-7所示的对话框,进行模板的选择。在这里还可以选择是否创建单元测试,为了养成一个良好的习惯,这里勾选“创建单元测试项目”复选框。这里选择“基本”模板,在项目开发中一般选择“空”或“基本”,因为这样的项目环境相对比较干净。

图3-7

有关项目模板的说明:

● Internet应用程序:外网访问的Web应用。

● Intranet应用程序:局域网访问的Web应用。

● 单页应用程序:也就是WebPages,这个现在用得很少。

● 移动应用程序:构建移动端程序。

● WebAPI:构建RESTful服务,轻量级API开发框架,微软之前有Wcf这一重型框架。

选择了“基本”模板并确定后会创建两个项目,即FirstMVCApp和FirstMVCApp.Tests,如图3-8所示。

图3-8

3.3.2 项目框架结构说明

1.默认项目模板中的内容

● App_Data:用来存储数据库文件,xml文件或者应用程序需要的一些其他数据

● Content:用来存放应用程序中需要用到的一些静态资源文件,如图片和CSS样式文件。Content:目录默认情况下包含了本项目中用到的css文件Site.css,以及一个文件夹themes:themes中主要存放jQuery UI组件中要用到的图片和css样式。

● Controllers:用于存放所有控制器类,控制器负责处理请求,并决定哪一个Action执行,充当一个协调者的角色。

● Models:用于存放应用程序的核心类,数据持久化类,或者视图模型。如果项目比较大,可以把这些类单独放到一个项目中。

● Scripts:用于存放项目中用到的JavaScript文件,默认情况下,系统自动添加了一系列的js文件,包含jquery和jquery验证等js。

● Views:包含了许多用于用户界面展示的模板,这些模板都是使用Rasor视图来展示的,子目录对应着控制器相关的视图。

● Global.asax:存放在项目根目录下,代码中包含应用程序第一次启动时的初始化操作,诸如路由注册。

● Web.config:同样存在于项目根目录,包含ASP.NETMVC正常运行所需的配置信息。

如果选择的是“Internet应用程序”模板,那么还会有favicon.ico文件:

● favicon.ico:存在于应用程序根目录,应用程序的图标文件显示在浏览器,名称不能更改,可以使用其他图片替换。

●Controllers目录下面默认会有两个控制器——HomeController(负责主页的请求处理)和AccountController(身份证验证)。

● Models目录中默认会含有一个AccountModels.cs.类,类中包含了一系列和身份验证相关的类,是项目默认为我们提供的一个模板。

2.添加控制器Blog

右击文件夹Controllers→添加→控制器→BlogController,添加如下代码:

/// <summary>
/// Action方法,返回ActionResult
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
      ViewBag.Message = "First ASP.NET MVC application."; //展现到视图中数据
      //~/Views/Home/Index.cshtml
      return View(); //展现指定的视图,当没有指定视图名称时,默认是指向根目录下Views文
      // 件夹中,子文件夹名称为当前控制器名称Home,视图名称和当前Action名称一样
}

3.添加视图

将鼠标移动到Index()方法体中的任意位置,右击→添加视图→确定,默认会在Views/Blog目录下面生成一个Index.cshtml文件。

在Index视图中添加代码:

@ViewBag.Message

4.运行

将FirstMVCApp设置为启动项目,然后按Ctrl+F5组合键或者选择“调试→开始执行”运行程序,这时VS会自动启动ASP.NET开发者服务器,并随机分配一个端口,以便于我们浏览ASP.NET程序。

运行会报错,提示“无法找到资源”,这是因为App_Start目录下面的RouteConfig.cs路由配置类中配置了默认路由,路由规则如下:

routes.MapRoute(
              name: "Default",
              url: "{controller}/{action}/{id}",
              defaults: new { controller = "Home", action = "Index", id =
              UrlParameter.Optional }
);

可以看到默认控制器是Home,我们将其修改为Blog,再按Ctrl+F5组合键运行,如图3-9所示。

图3-9

出现这个结果页面表示OK。

BlogController通过继承Controller来表示它是一个控制器类,类名的后缀和Controller一样。控制器通过URL来识别执行的是哪一个Action。

ViewBag本质上是一个字典,提供了一种View可以访问的动态数据存储。这用到了.NET 4.0的动态语言特性。你可以给ViewBag添加任意属性,并且这个属性是动态创建的,不需要修改类的定义就可以从View中访问。

3.3.3 路由——映射URL到Action

在ASP.NET MVC中是如何将URL映射到控制器中指定的Action的呢?

在Global.asax中,“RouteConfig.RegisterRoutes(RouteTable.Routes); ”这行语句进行了路由规则的注册。

打开App_Start目录下面的RouteConfig.cs文件,代码如下:

namespace FirstMVCApp
{
    public class RouteConfig
    {
      public static void RegisterRoutes(RouteCollection routes)
      {
          routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
          routes.MapRoute(
              name: "Default",
              url: "{controller}/{action}/{id}",
              defaults: new { controller = "Blog", action = "Index", id =
              UrlParameter.Optional }
          );
      }
    }
}

从这里可以看出应用程序启动的时候默认调用了BlogController控制器中的Index方法,而且控制器是不区分大小写的。

所以我们在地址栏中输入“http://localhost:4236/Blog/Index”、“http://localhost:4236/”以及“http://localhost:4236/BLog/Index”时访问的结果是一样的。

Action

我们可以看到ASP.NETMVC的请求都归结到Action上,所以是URL驱动,而且Action跟View是弱耦合的关系,因为我们可以在Action中的View()方法中指定视图名称。

(1)新建一个视图Article

右击Views目录下面的Blog目录,选择“添加→视图”,并将视图名称设置为Article,在视图中添加文字“我是文章”。

(2)新建一个Action ShowArticle

在Blog视图中添加一个Action方法ShowArticle(),代码如下:

public ActionResult ShowArticle()
{
      return View("Article");
}

运行程序,在浏览器输入“http:// localhost:4236/Blog/ShowArticle地址”,结果如图3-10所示。

图3-10

View模板显示页面的规则是先找对应的Controller文件夹,再找对应的Shared文件夹中所有继承自viewpage的页面。

3.3.4 返回string的MVC方法

在Blog控制器中添加如下代码:

public string Say()
{
      return "Hello, World! ";
}

运行,在地址栏输入“http://localhost:4236/Blog/Say”地址,运行结果如图3-11所示。

图3-11

提示 服务器在接收请求后会解析URL(根据路由表里配置的URL来分析类名和方法名)从中找到请求的类名,并在类名后面加上Controller作为真实的类名,创建该类的对象,并调用URL中指定的方法。

Blog控制器里面的Index方法返回了一个View()方法,表示返回加载一个视图,视图文件的路径默认是/View/控制器名称/Action名称.cshtml。

3.3.5 简单了解Razor视图

以cshtml为后缀的就是Razor视图。在ASP.NET MVC中,官方给出了两种默认视图,一种是ASPX(就是传统的WebForm),一种就是Razor。

在视图中,我们可以直接调用C#代码和代码块,只要在调用之前加一个@符号即可。代码块要用大括号括起来。

修改Index视图代码如下:

@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>
<body>
    @ViewBag.Message
    <div>
    @for (int i = 0; i < 3; i++)
    {
        <p>@i</p>
    }
   </div>
</body>

注意,修改View中的代码不需要重新编译项目,只需要按Ctrl+S组合键保存,然后刷新界面即可,运行结果如图3-12所示。

图3-12

3.3.6 ASP.NET MVC组件之间的关系

ASP.NET MVC组件之间的关系如图3-13所示。

● View和Controller都可以直接请求Model,但是Model不依赖View和Controller;

● Controller可以直接请求View来显示具体页面;

● View不依赖Controller, View可以通过另外的方式来请求Controller。

View Controller Model

图3-13