ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第一章:创建基本的MVC Web站点

  在这一章中,我们将学习如何使用基架快速搭建和运行一个简单的Microsoft ASP.NET MVC Web站点。在我们马上投入学习和编码之前,我们首先了解一些有关ASP.NET MVC和Entity Framework的背景信息,然后再详细学习如何搭建开发环境。

1.1 MVC和ASP.NET MVC

  这本书涵盖Microsoft版本的MVC,即ASP.NET MVC。在写本书的时候,ASP.NET MVC的生产版本为MVC5,因此,本书的示例代码都使用ASP.NET MVC 5编写。在本书中有一章内容涵盖ASP.NET Core 1.0 MVC (MVC 6)。

  MVC这三个大写字母分别表示Model-View-Controller(模型-视图-控制器),是一种广泛使用的软件开发设计模式。ASP.NET MVC由以下基本模块组成:

  • Models:是一些表示应用程序数据的类,这些类通常称之为普通CLR对象(Plain Old CLR Objects, POCOs)。这些类也用来封装和执行一些业务逻辑,比如,我们稍后看到的购物车的业务逻辑。
  • Views:是一些用于生成HTML的模板文件,生成的HTML文件将会被发送到浏览器。视图(View)通常用于展示从模型(Model)获取的数据。尽管视图(View)可以包含一些决定哪些HTML可以被生成的逻辑,但不应该包含任何业务逻辑。
  • Controllers:是一些用于处理输入请求的类,这些类可以从模型(Model)获取数据,并将这些数据传递给视图(View),最终在视图(View)生成的HTML中显示。控制器(Controller)可能会包含一些根据请求中的某些信息来过滤数据的逻辑。比如,我们可以根据传递给控制器(Controller)方法的参数(该参数的值来自于客户端请求)来生成查询。

  译者注:在本书后续翻译过程中,将会把Model翻译成模型、View翻译成视图、Controller翻译成控制器,不再使用英文描述。

  在本书中的示例代码有助于加深我们对模型、视图和控制器定义的理解,并在合适的时机使用更加高级的概念,比如视图模型(View Model)。

  MVC起源于70年代后期的Smalltalk项目,从此之后不断被更新并应用于多个技术领域。MVC的主要原则是要创建一个可分层的、可测试的以及可维护的应用程序体系架构。MVC的特点之一就是比较适合做单元测试,这主要得益于模型、视图和控制器的划分。单元测试在本书中没有涉及,如果想对单元测试有一个深入的理解,推荐大家阅读Adam Freeman的PRO ASP.NET MVC(中文名称:精通ASP.NET MVC 5)一书。

1.2 Entity Framework和Code First(代码优先)

  Entity Framework (EF)是一个对象关系映射(object relational mapping, ORM)框架,该框架是.NET Framework的一部分。本书将通篇使用Entity Framework的Code First方法编写类及它们之间的关系,然后在不使用任何SQL语句的情况下,生成数据库及对应的表。在编写本书时,Entity Framework可用版本为EF 6,然而在本书中有一章会涉及使用EF 7版本。在本书中的所有示例代码使用的都是SQL Server,但是,Entity Framework也可以用于其他关系型数据库,比如Oracle。

1.2.1 将Code Frist应用于现有数据库

  正如前面锁提到的,Code First是使用Entity Framework的一种方法,使用该方法可以允许我们首先编写Model类,然后根据模型类来生成数据库及对应的表,这比较适合数据库不存在的新建项目。但是,从EF 6.1开始,Code First也可以用于已存在的数据库,并且可以根据已存在的数据库生成Model类。这个主题我们会在本书后面章节深入讲解。

1.3 Web开发的软件需求

  本书所使用的是Visual Studio 2015 Community版本,这个可以在Microsoft站点免费下载,该版本几乎包含了Visual Studio 2015付费版本的所用功能,我们将使用这个版本编写本书的所有代码。在本书中我们还将使用Google的Chrome浏览器来运行和测试我们编写的代码,之所以使用Chrome浏览器,是因为该浏览器提供了非常优秀的针对开发人员工具。我们还推荐大家最好在拥有4GB内存的Windows PC机上运行Visual Studio。

  我们可以在以下链接中下载Visual Studio 2015 Community版本:https://www.visualstudio.com/zh-hans/downloads/

  注意:当我们安装Visual Studio 2015 Community的时候会自动安装SQL LocalDB,但是,在Windows 10系统上,可能需要我们单独安装SQL LocalDB。SQL Server Express可以在以下链接中下载:https://www.microsoft.com/zh-CN/download/details.aspx?id=42299

1.4 创建项目

  我们要做的第一件事就是使用Visual Studio创建一个使用ASP.NET MVC和Entity Framework的Web项目。启动Visual Studio,然后在菜单栏中依次选择【文件】->【新建】->【项目】,在弹出的“新建项目”窗体中,确保我们选择了【已安装】->【模板】->【Visual C#】->【Web】,然后选择“ASP.NET Web应用程序”项目类型,如图1-1所示。选择.NET Framework 4.6.1作为我们.NET的版本。

图1-1:选择AS.NET Web应用程序类型

  输入名称BabyStore,然后点击“确定”按钮继续。我们将看到另一个窗体,如图1-2所示。在这个窗体中,我们在ASP.NET 4.6.1模板中选择MVC,并确保身份验证为个人用户账户。

图1-2:选择MVC模板选项

  点击“确定”按钮创建项目,一旦项目创建完毕,我们将会看到一个写有“你的ASP.NET应用程序”的页面。关闭这个文件,因为我们不会用到它。看一下在Visual Studio右侧的解决方案资源管理器,Visual Studio使用一个名为基架的过程自动生成了一个基本的MVC项目,我们将使用这个项目作为我们项目的入口点。

  在解决方案资源管理器中展开Controllers、Models和Views文件夹,如图1-3所示。在Models文件夹下创建的文件我们将在后续的身份验证中用到。在这一章中,我们将学习HomeController类和它相关的视图。

图1-3:展开Controllers、Models和Views文件夹的解决方案资源管理器

1.4.1 查看Web站点

  从Visual Studio菜单栏中,选择【调试】->【开始执行(不调试)】,Web站点将会在Visual Studio所使用的浏览器中打开,如图1-4所示。要想改变所使用的浏览器,只需要在Visual Studio菜单栏的第二行中的下拉列表中选择一个不同的浏览器即可。

  注意:这个Web站点在运行时会使用Visual Studio赋给的一个随机端口。URL的通常模式为http://localhost:port/Controller/Action/AdditionalParameters(注:此处译者将http://localhost:port/Controller/View/AdditionalParameters中的View修正为Action)。当这个站点启动时,我们看到在URL中并没有显示控制器名或者动作方法名,这是因为在这个示例中,默认调用了Home控制器中的Index动作(Action)方法,而在Index动作方法中返回的是一个名为Index的视图。

图1-4:自动创建的MVC Web站点

1.4.2 主页是如何工作的

  在图1-4中之所以显示主页,是因为我们向Web站点发送了一个URL为/Home/Index的请求,之所以这个URL没有在浏览器的地址栏中显示,是因为它是应用程序启动时的默认URL。如果我们在图1-4中的URL后面添加/Home/Index,然后回车,会发现所显示的页面没有发生改变。

  上述URL告诉MVC Web应用程序,一个客户端请求被发送给Home控制器的Index动作方法。该动作方法在HomeController.cs文件中定义,如下面代码所示。该动作方法只包含一行简单的代码return View(),这行代码告诉Web站点要打开相对应的视图文件,在这个示例中,这个对应的视图文件是Views\Home\文件夹下的Index.cshtml。按照约定,ASP.NET MVC控制器的动作方法的默认视图文件可以在“Views\控制器名\动作方法名.cshtml”路径下找到。当然,我们可以改变这种约定,使得动作方法可以打开一个不同的视图,我们将在本书后续章节讲述。包含Index动作方法的Controllers\HomeController.cs文件的内容如下所示:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6
 7 namespace BabyStore.Controllers
 8 {
 9     public class HomeController : Controller
10     {
11         public ActionResult Index()
12         {
13             return View();
14         }
15
16         public ActionResult About()
17         {
18             ViewBag.Message = "Your application description page.";
19
20             return View();
21         }
22
23         public ActionResult Contact()
24         {
25             ViewBag.Message = "Your contact page.";
26
27             return View();
28         }
29     }
30 }

  Views\Home\Index.cshtml文件包含显示在主页中的与显示文本相关的HTML代码。在这个文件中,我们可以看到好几个HTML元素都带有class属性,这些class属性的值是Bootstrap的CSS类,这些类控制着Home页的布局。在后续章节中,我们将学习一些方法来改变Bootstrap以及如何在完全不使用Bootstrap的情况下重新设计我们的站点。

1.4.3 关于页面、联系方式页面和ViewBag

  除了注册和登录这两个链接之外,在主页还有另外两个页面的链接:关于和联系方式,它们链接到的URL分别为/Home/About和/Home/Contact。

  这两个URL链接遵循前面所讲的约定,即它们会分别调用Home控制器中的About动作方法和Contact动作方法,并且会加载Views\Home目录下的About.cshtml视图和Contact.cshtml视图。

  如果我们检查在上面代码中的About方法和Contact方法,我们会看到在这两个方法中都有一行代码使用了ViewBag。

  About动作方法包含的代码为ViewBag.Message = “Your application description page.”,Contact方法包含的代码为ViewBag.Message = “Your contact page.”,赋值的这两句话都显示在它们各自的视图中。

  如果我们查看About.cshtml文件的代码,会发现其中有一行代码为<h3>@ViewBag.Message</h3>,视图使用这一行代码来显示ViewBag的Message属性的值。当在浏览器中显示时,我们会看到“Your application description page”这行文本,如图1-5所示。

图1-5:通过ViewBag由控制器传递给About视图的显示信息

  ViewBag是一个动态对象,用于将数据传递给视图。由于其动态性,不推荐使用ViewBag给视图传递多个数据片段。ViewBag不是强类型,这意味着它可以包含任何数据,因此,我们在视图中使用它的时候没有智能提示功能。我们推荐使用强类型视图模型一次给视图传递多个数据片段。我们将在第三章讲述。

1.4.4 路由:Web站点是如何知道我们请求的是哪个控制器的哪个方法

  ASP.NET MVC使用ASP.NET的路由控制应用程序如何解释URL。它也控制着传递进来的HTTP请求的目标是哪个控制器的哪个方法,从而显示哪个视图。为了解释它是如何工作的,我们查看一下前面创建应用程序的时候自动生成的默认路由。

  打开App_Start文件夹下的RouteConfig.cs文件,在这个文件中的代码定义了应用程序以何种方式确定请求的URL和哪个控制器的那个动作方法相匹配。代码如下所示:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6 using System.Web.Routing;
 7
 8 namespace BabyStore
 9 {
10     public class RouteConfig
11     {
12         public static void RegisterRoutes(RouteCollection routes)
13         {
14             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
15
16             routes.MapRoute(
17                 name: "Default",
18                 url: "{controller}/{action}/{id}",
19                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
20             );
21         }
22     }
23 }

  我们感兴趣的代码是routes.MapRoute方法,在第17行定义了一个名为“Default”的路由。代码url: "{controller}/{action}/{id}"指示站点期望第一个片段为控制器的名字,其次是动作的名字(匹配控制器中的方法名),然后是一个名为id的片段。我们待会就会讨论id片段,但是,现在我们集中精力在控制器和动作方法片段上。

  default命名参数的值告诉应用程序当请求的URL中没有指定控制器或动作时,就使用其默认值,控制器的默认值是Home,动作的默认值是Index,由此会调用Views\Home下的Index.cshtml视图。这就是为什么当我们使用不带任何参数的URL时,Home页面会加载的原因。

1.4.4.1 使用可选URL的ID参数

  为了完成这个非常简单的默认路由设置的概述,我们修改这个站点的让它使用可选的ID参数。

  打开Controllers文件夹下的HomeController.cs文件,将其中的About方法的代码修改为下列代码:

1 public ActionResult About(string id)
2 {
3     ViewBag.Message = "Your application description page. You entered the ID " + id;
4
5     return View();
6 }

  我们告诉这个方法去处理传递给它的名为id的参数,这和默认路由设置中的可选的第三个参数名称相符合。ASP.NET MVC的模型绑定系统会自动将URL中的ID参数映射到About方法的id参数。我们将在后面的章节中详细讲述模型绑定。

  现在不调试启动Web站点导航到关于页面,然后在URL的后面添加一个ID,如下所示:http://localhost:5073/Home/About/7。

  这将把7作为ID参数的值传递给About方法,在该方法中我们将这个值添加到了ViewBag中,并在视图中显示出来。结果如图1-6所示。

图1-6:应用和处理一个可选URL的ID参数

  ASP.NET MVC也自动匹配任何与方法参数相匹配的HTTP请求中的参数。这种匹配是不区分大小写的。比如,我们输入的URL为http://localhost:5073/Home/About?id=7将会返回和前面相同的结果,这是因为在查询字符串中的id参数自动匹配About方法的id参数。在第二章我们还会详细讲述。

1.4.5 布局页的作用

  我们可能已经注意到了,当我们导航到不同的页面,这个站点显示一样的页头和导航菜单。这种效果是由布局页来完成的。在Views\Shared\_Layout.cshtml中的布局页的内容如下所示:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 5     <meta charset="utf-8" />
 6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7     <title>@ViewBag.Title - 我的 ASP.NET 应用程序</title>
 8     @Styles.Render("~/Content/css")
 9     @Scripts.Render("~/bundles/modernizr")
10
11 </head>
12 <body>
13     <div class="navbar navbar-inverse navbar-fixed-top">
14         <div class="container">
15             <div class="navbar-header">
16                 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
17                     <span class="icon-bar"></span>
18                     <span class="icon-bar"></span>
19                     <span class="icon-bar"></span>
20                 </button>
21                 @Html.ActionLink("应用程序名称", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
22             </div>
23             <div class="navbar-collapse collapse">
24                 <ul class="nav navbar-nav">
25                     <li>@Html.ActionLink("主页", "Index", "Home")</li>
26                     <li>@Html.ActionLink("关于", "About", "Home")</li>
27                     <li>@Html.ActionLink("联系方式", "Contact", "Home")</li>
28                 </ul>
29                 @Html.Partial("_LoginPartial")
30             </div>
31         </div>
32     </div>
33     <div class="container body-content">
34         @RenderBody()
35         <hr />
36         <footer>
37             <p>&copy; @DateTime.Now.Year - 我的 ASP.NET 应用程序</p>
38         </footer>
39     </div>
40
41     @Scripts.Render("~/bundles/jquery")
42     @Scripts.Render("~/bundles/bootstrap")
43     @RenderSection("scripts", required: false)
44 </body>
45 </html>

  如果我们打开这个文件,我们会看到它包含了站点导航的一些HTML元素。在该文件中的@RenderBody()方法会将请求的视图内容插入到布局标记之中。

  Views\_ViewStart.cshtml文件中的内容指定了Web站点使用Views\Shared\_Layout.cshtml文件作为主布局页。框架会将此文件的内容视为视图的一部分,因此可以有效地将其内容添加到每个视图的开始部分。下面的代码显示了_ViewStart.cshtml文件的内容,它指定我们的站点将使用哪个布局页。

1 @{
2     Layout = "~/Views/Shared/_Layout.cshtml";
3 }

  提示:如果我们不想让一个视图使用_ViewStart.cshtml文件中指定的布局页,我们可以在这个视图文件的最上面添加@{ Layout = null; }。

 1.5 小节

  在这一章中,我们仅仅对ASP.NET MVC和Entity Framework做了一个非常简单的概览,并展示了在本书中我们将会一直使用的创建项目的方式,并解释了Web站点的基础,包括控制器、视图、ViewBag和路由。我们只所以在本章中做了简单描述,是因为在本书的后续章节中我们会详细解释这些概念,并指导我们快速开发一个数据驱动的Web站点。我们可能已经注意到了,在本章中我们没有涉及任何有关模型的知识,这是因为该部分知识是我们下一章的内容,在下一章我们将对我们的Baby Store站点添加一些产品和分类。

时间: 2024-10-26 05:06:15

ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第一章:创建基本的MVC Web站点的相关文章

ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类.指定数据库连接字符串以及创建一个数据库.最后,我们还将添加视图和控制器来管理和显式产品和分类数据. 注意:如果你想按照本章的代码编写示例,你必须完成第一章或者直接从www.apress.com下载第一章的源代码. 2.1 添加模型类 Entity Framework的代码优先模式允许我们从模型类创

ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之目录导航

ASP.NET MVC with Entity Framework and CSS是2016年出版的一本比较新的.关于ASP.NET MVC.EF以及CSS技术的图书,我将尝试着翻译本书以供日后查阅.但是,由于本人英语水平有限,难免有翻译不准确或错误的地方,请大家踊跃提出宝贵的意见,以进行修正.本书一共18章,下面列出各章的英文目录: Chapter 1: Building a Basic MVC Web Site Chapter 2: Creating Views, Controllers,

ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第三章:搜索、高级过滤和视图模型

在这一章中,我们首先添加一个搜索产品的模块以增强站点的功能,然后使用视图模型而不是ViewBag向视图传递复杂数据. 注意:如果你想按照本章的代码编写示例,你必须完成第二章或者直接从www.apress.com下载第二章的源代码. 3.1 添加产品搜索 为了执行产品搜索,我们将添加一些功能使其能够按照产品名称.描述和分类进行搜索,从而让用户有一个更好的选择来查找相关结果. 之所以将分类也包含在内,是因为如果用户输入的是"clothes",而不是一件特定的衣服,那么所有的衣服都会被搜索到

ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第六章:管理产品图片:多对多关系(上)

这章介绍了怎样创建一个新的实体来管理图片,怎样使用HTML窗体来上传图片文件和使用多对多关系来使它们与产品相关,并且怎样来保存图片到文件系统中.这章也介绍了更多复杂的错误处理增加客户端错误到模型中为了把它们显示回给用户.在这章中播种数据库使用的产品图片可能在在第六章的从Apress网页站点下载代码中. 注意:如果你想遵从这章的代码,你必须完成第五章的代码或者从www.apress.com下载第五章的源代码作为一个起点. 创建实体保存图片文件名 这个项目,我们正要使用文件系统在Web项目中存储图片

《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章  ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架,它支持3种不同的技术来创建websites(网站)和Web应用:他们分别是,Web Pages,Web Forms,和MVC.虽然MVC是一种非常流行的,有完整的用于软件开发模式理论的技术,但它在ASP.NET中却是一种新的技术. 目前最新的版本是2012年发布的ASP.NET MVC4.自从2008年发布

《Entity Framework 6 Recipes》中文翻译系列 (40) ------ 第七章 使用对象服务之从跟踪器中获取实体与从命令行生成模型(想解决EF第一次查询慢的,请阅读)

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-5  从跟踪器中获取实体 问题 你想创建一个扩展方法,从跟踪器中获取实体,用于数据保存前执行一些操作. 解决方案 假设你有如图7-7所示的模型. 图7-7. 包含实体Technician和ServiceCall的模型 在这个模型中,每个技术员(technician)都有一些业务服务请求(service call),业务服务请求包含联系人姓名,问题.使用代码清单7-4,创建一个扩展方法获取

《Entity Framework 6 Recipes》中文翻译系列 (33) ------ 第六章 继承与建模高级应用之TPH与TPT (2)

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 6-8  嵌套的TPH建模 问题 你想使用超过一层的TPH继承映射为一张表建模. 解决方案 假设你有一张员工(Employee)表,它包含各种类型的员工,比如,钟点工,雇员.如图6-10所示. 图6-10 包含各种类型的员工表 Employee表包含钟点工,雇员,提成员工,这是雇员下面的一个子类型.按下面的步骤,使用派生类型HourlyEmployee,SalariedEmployee和Sa

《Entity Framework 6 Recipes》中文翻译系列 (32) ------ 第六章 继承与建模高级应用之TPH与TPT (1)

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 6-6  映射派生类中的NULL条件 问题 你的表中,有一列允许为null.你想使用TPH创建一个模型,列值为null时,表示一个派生类型,不为null时,表示另一个派生类型. 解决方案 假设你有一张表,描述医学实验药物.这张表包含一列指示该药是什么时候批准生产的.药在批准生产之前都被认为是实验性的.一但批准生产,它就被认为是药物了.我们就以图6-7中Drug表开始我们这一小节的学习. 图6

《Entity Framework 6 Recipes》中文翻译系列 (30) ------ 第六章 继承与建模高级应用之多对多关联

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第六章  继承与建模高级应用 现在,你应该对实体框架中基本的建模有了一定的了解,本章将帮助你解决许多常见的.复杂的建模问题,并解决你可能在现实中遇到的建模问题. 本章以多对多关系开始,这个类型的关系,无论是在现存系统还是新项目的建模中都非常普遍.接下来,我们会了解自引用关系,并探索获取嵌套对象图的各种策略.最后,本章以继承的高级建模和实体条件结束. 6-1  获取多对多关联中的链接表 问题