ASP.NET MVC程序设计教程(第3版)
上QQ阅读APP看书,第一时间看更新

1.2 创建和配置ASP.NET MVC 5项目

安装VS2013开发环境后,可直接创建【ASP.NET Web应用程序】项目。为了方便读者学习,并且对项目的模块组织和完整实现有一个全面的了解和把握,本书配套的所有源程序都将包括在这一节创建的Mvc5Examples项目中。

1.2.1 创建项目

这一节我们学习如何创建新项目,并配置项目中使用的程序包版本。

1.新建项目

运行VS2013,单击【新建项目】,在弹出的窗口中,选择【ASP.NET Web应用程序】模板,修改项目名为Mvc5Examples,输入或选择一个合适的项目保存位置(如E:\ls\),如图1-5所示,单击【确定】按钮。

图1-5 创建ASP.NET Web应用程序项目

在接下来弹出的窗口中,单击【MVC】,同时勾选其下方的【MVC】和【Web API】选项,如图1-6所示,单击【确定】按钮。

图1-6 选择模板

在该模板中,身份验证默认使用的是Owin中间件,由于该内容涉及很多其他方面的扩展知识和实现技术,限于教材篇幅,本书不介绍这部分相关的内容,但仍然在项目中保留了模板自动生成的身份验证相关的代码,以方便读者自学。

2.观察项目结构

在【解决方案资源管理器】中,观察项目默认自动创建的文件夹,各文件夹的含义如表1-1所示。

表1-1 项目默认创建的文件夹

除了这些文件夹之外,该项目还使用Global.asax文件来设置全局URL路由默认值,同时,还会使用项目根目录下的Web.config文件来配置全局应用程序。

3.修改项目启动页

由于VS2013包含的ASP.NET支持模型联编技术,因此,默认情况下,它将项目启动页配置为当前页,这样做的好处是使用【Web窗体】模型时可直接观察某一个网页的运行效果。但是,由于我们希望每次都从主页开始运行,所以需要修改项目启动页的配置。

选择主菜单的【项目】→【Mvc5Examples属性】命令,如图1-7(a)所示,即可打开项目属性配置。在属性配置界面中,单击【Web】选项卡,将创建项目时系统默认的【当前页面】更改为【特定页】,特定页右侧的文本框内不需要输入任何内容,直接按<Ctrl>+S键保存配置即可,如图1-7(b)所示。

图1-7 修改项目启动操作为运行特定页

4.运行模板默认提供的主页

为了方便初学者学习,模板默认已经包含了一些简单的示例代码,创建项目后,按<F5>键直接运行应用程序,观察模板默认主页在IE 11.0浏览器中运行的效果,如图1-8所示。

图1-8 模板默认提供的主页运行效果

1.2.2 使用NuGet更新程序包

程序包用于保存当前项目引用的其他文件及其版本信息。

VS2013自带的NuGet提供了非常方便的程序包更新方式。需要更新项目自动生成的程序包的原因有两点:一是新版本修订了已经发现的旧版本的bug,二是新版本与旧版本相比有些功能的使用更加简单。比如,Bootstrap 3.3.2版(或更高版本)提供的有些CSS类在Bootstrap 3.0版中并不存在,而Bootstrap 3.0版中的一些bug由于在3.3.2版中已经更正了,因此不会再出现这些bug等。

注意:更新程序包只影响当前项目,不会影响新建的项目或者其他已经存在的项目。另外,更新程序包时,会自动替换当前项目中相关的文件和引用,不需要手工修改。

下面介绍具体更新步骤,这些更新步骤需要本机可访问Internet网。

1.更新当前项目的程序包

打开Mvc5Examples项目,选择主菜单的【项目】→【管理NuGet程序包】命令,如图1-9所示。

图1-9 利用NuGet管理程序包

在弹出的窗口中,先选择左侧【更新】选项卡下方的【全部】选项,然后单击该窗口中的【全部更新】按钮,如图1-10所示。

图1-10 更新当前项目的程序包

此时它就会自动将最新版本的更新包替换掉当前项目中的程序包版本。

完成更新程序包的步骤后,打开项目根目录下的packages.config文件,观察程序包配置文件中包含的内容和更新后对应的版本信息。

关闭项目,然后重新打开项目,以便VS2013正确加载最新版的程序包。

2.添加jQuery UI

默认情况下,Bootstrap和jQuery UI的同名组件会产生冲突,但是,如果我们解决了这些冲突,就可以在同一个项目中同时使用Bootstrap和jQuery UI。

由于本书各章的导航页是用jQuery UI来实现的,所以必须将它添加到当前项目中。

选择主菜单的【项目】→【管理NuGet程序包】命令,添加如图1-11所示的引用。

图1-11 添加jQueryUI

选择jQuery UI(Combined Library)后,单击【安装】按钮,它就会自动将其下载到当前项目中。

3.添加Microsoft jQuery Unobtrusive Ajax

Microsoft jQuery Unobtrusive Ajax用于实现页面局部更新。使用MVC提供的Ajax帮助器时,如果希望直接用jQuery ajax实现局部更新的功能,或者希望看到页面局部更新期间显示的提示信息,必须添加对该脚本文件的引用,如图1-12所示。

图1-12 添加Microsoft jQuery Unobtrusive Ajax

选择Microsoft jQuery Unobtrusive Ajax后,单击【安装】按钮,它就会自动将其下载到当前项目中。

1.2.3 修改项目配置

使用MVC开发ASP.NET Web应用程序时,可利用App_Start文件夹下的捆绑配置(BundleConfig.cs文件)优化CSS文件以及Bootstrap、jQuery等脚本文件的引用。

捆绑(Bundling)是指将多个文件合并到单个文件中。由于捆绑后加载的文件数量减少了,客户端访问网站时HTTP请求的次数也会相应减少,因此这种方式可以改善浏览器首次加载网页的负载性能,同时,捆绑技术也解决了项目引用的CSS和js文件版本更新后还需要修改网页中相关代码的问题。

1.修改捆绑配置

打开App_Start文件夹下的BundleConfig.cs的文件,将其改为下面的内容:

  using System.Web;
  using System.Web.Optimization;
  namespace Mvc5Examples
  {
      public class BundleConfig
      {
          public static void RegisterBundles(BundleCollection bundles)
          {
              //jQuery基本功能
              bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                          "~/Scripts/jquery-{version}.js"));
              //jQuery的非介入式ajax
              bundles.Add(new ScriptBundle("~/bundles/jquery/unobtrusive-ajax")
                       .Include("~/Scripts/jquery.unobtrusive*"));
              //jQuery客户端验证
              bundles.Add(new ScriptBundle("~/bundles/jquery/validate").Include(
                          "~/Scripts/jquery.validate*"));
              //jQueryUI的脚本
              bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                           "~/Scripts/jquery-ui-{version}.js",
                           "~/Scripts/jquery-ui-datepicker-cn.js"
                           ));
              //开发和调试程序用的Modernizr的版本
              bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                          "~/Scripts/modernizr-*"));
              //Bootstrap和respond脚本
              bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                        "~/Scripts/bootstrap.js",
                        "~/Scripts/respond.js"));
              //模板默认使用的CSS文件
              bundles.Add(new StyleBundle("~/Content/css").Include(
                        "~/Content/bootstrap.css",
                        "~/Content/Site.css"));
              //jqueryUI的CSS文件
              bundles.Add(new StyleBundle("~/Content/themes/base/jquery-ui").Include(
                        "~/Content/themes/base/all.css"));
              //true表示自动进行捆绑【将js全部捆绑到一个文件中】和缩小【自动选择.min.*的文件】。
              //     这种方式由于缩小了文件大小和加载文件的次数,因此加载速度稍快,但调试困难。
              //false表示不进行捆绑和缩小。
              BundleTable.EnableOptimizations = true;
          }
      }
  }

这些代码的含义请参看对应的注释。另外,jquery-ui-datepicker-cn.js是手工添加的新建JavaScript文件,该文件用于显示中文格式的日期选择器。

限于篇幅,我们不准备介绍捆绑框架的技术原理和实现细节,如果读者希望进一步了解捆绑框架的更多技术,请参看其他相关资料。

在Global.asax文件中,下面的代码会自动注册捆绑配置,下面是创建项目时系统自动添加的代码:

  BundleConfig.RegisterBundles(BundleTable.Bundles);

打开Views/Shared文件夹下的_Layout.cshtml文件,可看到下面的引用代码:

  <!DOCTYPE html>
  <html>
  <head>
      ......
      @Styles.Render("~/Content/css")
      ......
  </head>
  <body>
      ......
      @Scripts.Render("~/bundles/jquery")
      @Scripts.Render("~/bundles/bootstrap")
      ......
  </body>
  </html>

这段代码中的@Styles.Render(...)引用的就是BundleConfig.cs文件中定义的CSS捆绑配置,@Scripts.Render(...)引用的是BundleConfig.cs文件中定义的脚本捆绑配置。

在后续的章节中,我们还会学习如何在自定义的布局页中引用修改后的捆绑配置,这里只需要了解相关代码和捆绑配置文件的关系即可。

2.修改脚本引用配置

VS2013在Scripts文件夹下提供了一个_references.js文件,该文件的用途是让开发人员在键入JavaScript脚本代码时可看到对应的智能提示。

默认情况下,当在项目中新建一个JavaScript文件(扩展名为“.js”的文件)或者向项目中添加一个现有的脚本文件时,系统都会自动在_references.js文件中添加一个对该脚本文件的引用。这种默认设置的方便之处是不需要开发人员去手工修改_references.js,但这种设置仅适合项目中脚本文件不多的场合。如果项目中的脚本文件非常多,这种默认设置会给智能提示带来很大的性能问题,甚至可能导致智能提示失效。

为了解决智能提示的问题,打开该文件,将下面的代码:

  /// <autosync enabled="true" />

修改为:

  /// <autosync enabled="false" />

这样修改以后,即使项目中的脚本文件再多,也不会影响智能提示。此时,当在视图页或者分部页中希望看到布局页中引用的脚本文件智能提示时,需要手工将被引用的脚本文件从解决方案资源管理器中拖放到Scripts文件夹下的_references.js文件中。

修改后的_references.js文件请参看源程序,此处不再列出源代码。

1.2.4 创建项目主页和布局页

创建项目主页时,实际上直接修改Views/Home文件夹下模板自动生成的Index.cshtml文件即可。但是,为了重现模板默认的主页,并理解MVC是如何找到指定的主页位置的,我们不准备覆盖模板默认的主页,而是采用新建页面的办法来创建本书使用的主页。

另外,这一节我们还将介绍如何创建布局页。

1.添加布局页(_MainLayout.cshtml文件)

布局页也叫模板页,布局页的文件名建议用下划线开头,表示这种网页只能被其他页面引用,无法单独显示。

创建项目时,在Views文件夹的Shared子文件夹下,有一个系统自动添加的默认布局页(_Layout.cshtml文件),该文件的作用和Web窗体中母版页的作用相似。

下面我们再添加一个文件名为“_MainLayout.cshtml”的文件,作为本书主页默认引用的布局页。具体办法如下:鼠标右击Views文件夹下的Shared子文件夹,选择【添加】→【新建项】命令,在弹出的窗口中,选择【MVC 5布局页(Razor)】模板,将文件名称改为“_MainLayout.cshtml”,如图1-13所示,单击【添加】按钮。

图1-13 添加布局页

将_MainLayout.cshtml文件改为下面的内容:

  <!DOCTYPE html>
  <html>
  <head>
      <meta charset="utf-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>@ViewBag.Title</title>
      <link href="~/Content/bootstrap.css" rel="stylesheet" />
      <link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
      @Scripts.Render("~/bundles/modernizr")
      @Scripts.Render("~/bundles/jquery")
      @Scripts.Render("~/bundles/bootstrap")
  </head>
  <body>
      <div class="container">
          <img src="/common/images/home/mainpage.jpg"
                style="width: 100%; height: 153px;" />
      </div>
      <div class="container">
          <nav class="navbar navbar-inverse">
              <nav class="navbar-header">
                  <button type="button" class="navbar-toggle"
                           data-toggle="collapse" data-target=".navbar-collapse">
                      <span class="icon-bar"></span>
                      <span class="icon-bar"></span>
                      <span class="icon-bar"></span>
                  </button>
              </nav>
              <nav class="navbar-collapse collapse">
                  <ul class="nav navbar-nav">
                      <li>@Html.ActionLink("第1章", "Index", "ch01NavDemos",
                           new { area = "Chapter01", id = "ch01Index" }, null)</li>
                      @for (int i = 2; i <= 9; i++)
                      {
                          var areaName = "Chapter" + i.ToString("d2");
                          var chIndex = string.Format("ch{0:d2}Index", i);
                          <li>
                              @Html.ActionLink(
                              string.Format("第{0}章", i),   //链接提示信息(linkText)
                              "Index",  //操作方法名(actionName)
                              string.Format("ch{0:d2}Demos", i), //控制器名
                              new { area = areaName ,id = chIndex}, //路由参数(routervalues)
                              null  //HTML特性(htmlAttributes)
                           )
                          </li>
                      }
                      <li>@Html.ActionLink("第10章", "Index", "ch10",
                             new { area = "Chapter10", id = "ch10Index" }, null)</li>
                  </ul>
                  <ul class="nav navbar-nav navbar-right">
                      <li>@Html.ActionLink("模拟运行", "emulator", "Home",
                           new { area = "" }, null)</li>
                  </ul>
              </nav>
          </nav>
          @RenderBody()
          <div class="panel-footer  text-center">
              @Html.ActionLink("转到模板默认的主页", "Index", "Home")
          </div>
      </div>
  </body>
  </html>>

在这个布局页中,我们将所有脚本引用都放到了head块内,这样做的好处是在视图页和分部页中都可以直接引用项目中的脚本。如果将其放到body块的末尾,除非在分部页中重复添加脚本引用,否则会出现“$未定义”的错误。

另外,首次添加布局页后,MVC会自动将布局页模板附加到快捷菜单中,以后再次添加布局页时,只需要从快捷菜单中选择模板就可以了。

2.添加本书示例使用的主页

创建Mvc5Examples项目后,系统会自动在项目根目录下的Controllers文件夹下添加一个名为HomeController.cs的文件,并自动在该文件中添加一个名为Index的操作方法。同时,系统还会自动在项目根目录下的Views文件夹下创建一个名为Home的子文件夹,该文件夹的名称是HomeController去掉Controller后缀得到的结果。

下面我们在此基础上继续添加其他的代码。

打开HomeController.cs文件,在该文件中添加一个名为MainIndex的操作方法:

  public class HomeController : Controller
  {
      ......
      public ActionResult MainIndex()
      {
          ViewBag.Message = "ASP.NET MVC程序设计教程(第3版)";
          return View();
      }
  }

鼠标右击MainIndex操作方法,选择【添加视图】,弹出如图1-14所示的窗口。

图1-14 添加视图

在该窗口中,确认视图名称为“MainIndex”,勾选“使用布局页”,单击【添加】按钮。此时,在“/Views/Home”文件夹下,可看到系统自动添加了一个文件名为MainIndex.cshtml的文件,该文件将作为本书默认的主页。

双击MainIndex.cshtml打开该文件,将其改为下面的内容:

  @{
      ViewBag.Title = "主页";
  }
  <h2>@ViewBag.Message<small>-- 用C#和MVC5编写ASP.NET Web应用程序</small></h2>
  <div class="progress">
      <div  class="progress-bar  progress-bar-info  progress-bar-striped  active"
style="width: 100%"></div>
  </div>
  <div class="row">
      <div class="col-md-4">
          <h3>第1部分(1~8章)<small>基本技术</small></h3>
     <p>介绍ASP.NET MVC 编程基础、HTML5、CSS3、Bootstrap、jQuery以及数据库应用等基本用法。
</p>
      </div>
      <div class="col-md-4">
          <h3>第2部分(9~10章)<small>高级技术</small></h3>
          <p>介绍Web API、OData、SVG、Canvas、WebGL等高级应用编程技术。</p>
      </div>
      <div class="col-md-4">
          <h3>附录<small>上机练习和综合设计</small></h3>
          <p>提供了与本书内容配套的上机练习题,以及通过小组成员共同合作完成的综合设计题。</p>
      </div>
  </div>

3.修改路由配置

打开App_Start文件夹下的RouteConfig.cs文件,将代码中defaults的action = "Index"改为action = "MainIndex":

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

RouteConfig.cs文件用于控制项目默认的路由配置,将其中的Index改为MainIndex后,项目启动时就会自动运行/Views/Home文件夹下的MainIndex.cshtml文件。

4.修改“/Views/Shared”文件夹下的“_ViewStart.cshtml”文件

大部分情况下,视图都会引用某个布局页,为了避免在每个视图中都指定它所引用的布局页,一般在项目的_ViewStart.cshtml文件中一次性指定这些视图所引用的布局页。

打开“/Views/Shared”文件夹下的“_ViewStart.cshtml”文件,将其改为下面的内容:

  @{
      Layout = "~/Views/Shared/_MainLayout.cshtml";
  }

这样一来,Home子文件夹下的所有视图都会将_MainLayout.cshtml文件作为默认引用的布局页。

5.运行应用程序

在快捷工具栏中,选择【Internet Explorer】选项,然后按<F5>键在调试模式下运行应用程序,或者按<Ctrl>+<F5>键在非调试模式下运行应用程序,稍等片刻就会在IE 11.0浏览器中看到程序运行的效果,如图1-15所示。

图1-15 本书主页的运行效果

至此,我们创建了本书所有示例使用的主页,并观察了主页运行的效果。但是,由于还没有完成各章的实现代码,因此单击各章的超链接会显示找不到网页的错误,在后续的介绍中,我们会陆续添加其他的代码。