zoukankan      html  css  js  c++  java
  • 一个真正的应用程序(第7~8章)(所需代码在下一篇随笔里)

    第7章

      7.1 项目准备

        1、创建解决方案和项目

        2、安装工具包(Ninject 和 Microsoft.Aspnet.Mvc)

        3、添加项目之间的引用

        (4、设置 DI 容器)

          首先在 “项目名称.WebUI” 项目中添加一个文件夹,并在其中添加一个名称为 NinjectDependencyResolver.cs 的类文件。(文件内容比较固定)

          然后在 App_Start / NinjectWebCommon.cs 文件中完成依赖项解析器的注册。(代码也比较固定)

      7.2 从域模型开始

        1、在 XXX.Domain 项目中创建“实体类”文件夹 “Entities”,在文件夹中创建“产品类”“Product”

        2、创建抽象存储库 “IProductsRepository” 接口(添加新项,接口模板)。实现代码:IEnumerable<Product> Products { get; }

      7.4 准备数据库

        以 SQL Server 作为数据库,并用 Entity Framework(实体框架,EF)来访问数据库

        EF 是 Microsoft.NET 的 ORM(对象关系映射)框架。ORM 框架让开发人员可以用规则的 C# 对象来表示关系数据库的表、列和行。

        1、创建数据库(利用 LocalDB 创建本地数据库)

          第一个步骤是在 Visual Studio 中创建数据库连接:从 “视图” 菜单中打开 “服务器资源管理器” 窗口,单击 “连接到数据库” 按钮。

          然后在 “选择数据源” 对话框中选中 “SQL Server” 选项,然后单击 “继续” 按钮。(如果在其他项目中已经创建了数据库连接,将不会看到这个窗口)

          接着将看到 “添加连接” 对话框,将“服务器名”设置为 “(localdb)v11.0”,这是一个特殊名称,表示你希望使用 LocalDB 特性。(对于有的电脑可能要稍作改变)。选中 “使用 Windows 认证” 单选按钮,并设置数据库名称。

          单击 “确定” 按钮后,Visual Studio 会弹出一个将要创建新的数据库的提示对话框,单击 “是” 按钮继续。(在服务器资源管理器窗口的数据连接部分会出现一个新的条目,展开这个条目可以看到该数据库的各个方面)

        2、设计数据表(这里只设计一张 Product 表)

        3、向表中添加数据(也可以写好动作方法之后由动作方法来添加,这里是因为要做的是显示列表的功能)

        4、创建 Entity Framework 上下文

          Entity Framework 的最新版包含了一个很好的特性,叫做 “代码先行”。其思想是先定义模型中的类,再通过这些类生成数据库。

          由于刚才创建了数据库,笔者打算演示的是一种变异的“代码先行”,以此将模型类与现有的数据库关联起来。

          (1)通过 NuGet 命令行引入 EF 库包(两个项目都要引入,以便在两个项目中创建一些访问数据库的类)

          (2)创建上下文类,以便模型与数据库关联起来。(在 XXX.Domain 项目中创建一个 “Concrete”文件夹,并在里面添加一个 “EFDbContent.cs” 类文件)

              为了利用 “代码先行” 特性,需要创建一个派生于“System.Data.Entity.DbContent”的类。—— 即上下文类。该类会为数据库中的每个表自动地定义一个属性(真的是自动吗)

              该属性的名称为数据表名,而 DbSet 结果的类型参数为模型类型,由 EF 用于表示数据表的各个数据行。

          (3)告诉 EF 如何连接到数据库。

              在 XXX.WebUI 项目的 Web.config 文件中添加一条数据库连接字符串。(该连接字符串的名称与这个上下文类的名称相同。也许这才保证了上边所说的“自动”)(代码:)

        5、创建 Product 存储库

          剩下的工作就是在 XXX.Domain 项目的“Concrete”文件夹中添加一个类文件,其名称为 “EFProductRepository”。(Product 存储库类)

          该类实现了 IProductsRepository 接口(抽象存储库接口,而且是与 Product 类相关的存储库接口),并使用一个 EFDbContent 实例,以便用 EF 接收数据库的数据

          在对该存储库添加特性时,便会看到笔者是如何使用 EF 的。(而且它是多么简单)

          为使用这个新的存储库类,需要编辑 Ninject 绑定。编辑 NinjectDependencyResolver.cs 类文件中的 AddBindings 方法:

          (1)引入命名空间:XXX.Domain.Concreat;    //存储库所在命名空间

          (2)用抽象存储库接口和存储库实现类进行绑定。

      7.5 添加分页(实现分页显示)

        1、显示页面链接

          笔者需要在每个产品列表的底部渲染某种页面链接,以使客户能够在页面之间进行导航。

          为此,笔者打算实现一个可重用的 HTML 辅助器方法,该辅助器方法(在 PagingHelper 类中定义的拓展方法 PageLinks)将为所需的导航链接生成 HTML 标记

          (1)添加视图模型(PagingInfo 类)

              为了支持 HTML 辅助器方法,笔者打算把可用页面数、当前页,以及存储库中产品总数等方法的信息传递给视图。(最容易的做法是创建一个视图模型)

              在 XXX.WebUI 项目的 Models 文件夹中添加一个类文件,名称为 PagingInfo。

              视图模型不属于域模型,它只是一种便于在控制器与视图之间传递数据的类。(所以将它放在 XXX.WebUI 项目中,以使它与域模型的类分离开来)

          (2)添加 HTML 辅助器方法

              PageLinks 扩展方法使用 PagingInfo 对象中提供的信息生成一组页面链接的 HTML 标记。

              在需要使用该扩展方法的视图中需要引入该类文件所在的命名空间。(只有当包含扩展方法的命名空间在范围内时,其中的扩展方法才是可用的)

              (可以在视图专用的配置文件 Views / Web.config 中添加一条配置条目,或在视图上添加一条 @using 语句)

          (3)添加视图的模型数据

              至此仍尚未做好使用 HTML 辅助器方法的准备,还需要为视图提供一个 PagingInfo 视图模型类实例(该实例是 PageLinks 辅助器方法的一个参数),

            可以使用 “视图包” 特性类做这件事,但更好的做法是将控制器发送给视图的所有数据封装成一个单一的视图模型类

              为此,笔者在 Models 文件夹中添加了一个新的类文件,名称为“ProductListViewModel.cs”

          (4)显示页面链接

              首先在要显示分页链接的视图中引入对应的视图模型对象所在的命名空间。

              然后添加显示页面链接对应的代码。(在下一篇文章中有对应的代码)

          (5)改进路由设置

              重要的是默认的那条路由设置应该在新添加的路由配置的前面。(如果默认的那条还有用的话)

              路由系统是按路由列出的顺序进行处理的。

      7.6 设置内容样式

        1、安装 Bootstrap 包

        2、在布局(页)中运用 Bootstrap 样式。(也在嵌入页中使用)

        3、创建分部视图

          分部视图是嵌入到另一个视图中的一个内容片段,而不是一个模板

          创建分部视图:右击 /Views/Shared 文件夹,添加视图,模板选择“空”,选择对应的模型类,选中 “创建为分部视图”

          使用分部视图:@Html.Partial("分部视图名称", 模型类对象)

        通过阅读本章,读者需要理解,从事 MVC 应用程序的开发总要先做一些基础性的工作。(例如:建立基本的域模型、数据存储库,以及建立 DI 和良好的 URL 方案等)

    第8章 导航

      8.1 添加导航控件

        如果客户能通过产品分类对产品进行导航,则该应用程序会更加适用。这需要从三个方面入手:

           ① 增强控制器类中的动作方法,以使它能够过滤存储库中的 Product 对象。

           ② 重新考察并增强 URL 方案,并且修订路由策略。

           ③ 创建一个产品分类列表,将其放入网站工具栏,高亮显示当前分类,并对其他分类进行链接。

        1、过滤产品列表

            (1)本小节打算从增强视图模型类 ProductListViewModel 开始。(为了渲染工具栏,笔者需要将当前分类传递给视图

            (2)更新 Product 控制器,以使 List 动作方法能通过分类来过滤 Product 对象并利用添加到视图模型的新属性来指示已选择了哪个分类

            主要对动作方法 List 做了3处修改:

                添加了一个名为 category (代表了所选分类)的参数;

                在列表中使用这个 category 参数,以使 LINQ 查询得到增强。(如果 category 非空,则只选出与 Category 属性匹配的那些 Product 对象)

                最后一处修改是设置添加到 ProductListViewModel 类上的 CurrentCategory 属性的值

        2、调整 URL 方案

            重要的是要注意路由添加的顺序。(路由是按其定义的顺序来运用的,如果改变这种顺序,会得到奇怪的效果)

            MVC 用 ASP.NET 的路由系统处理来自客户端的输入请求,但也用它生成输出 URL。(这种输出 URL 符合 URL 方案,并可以嵌入到 Web 页面之中

            通过路由系统处理输入请求并生成输出 URL,可以确保应用程序中的所有 URL 是一致的

            Url.Action 方法是生成输出链接最方便的办法。(所以,用该方法来作为扩展方法 PageLinks 的第二个参数,注意带上实参)

            现在,既然已经添加了对分类过滤的支持,就需要回过头来把这个信息传递给该辅助器方法。

        3、建立分类导航菜单

            程序需要一个显示可用分类的列表并指示出它们之中哪一个是被当前选中的

            随着应用程序的扩建,将在不止一个控制器中使用这个分类列表,因此,需要确保它是自包含且可重用的

            ASP.NET MVC 框架具有一种叫做 “子动作” 的概念,它特别适用于创建诸如可重用导航控件的情况

            子动作依赖于叫做 “Html.Action” 的 HTML 辅助器方法它让你能够在当前视图中包含一个任意动作方法的输出

            (1)在这里,可以创建一个新控制器,称为 “NavController”它带有一个动作方法,称为 “Menu”该方法渲染了一个导航菜单。(生成分类列表)

                笔者不希望在控制器中生成分类的 URL,笔者打算在视图中使用一个辅助器方法来做这件事。

                (要记住控制器的职责 —— 它只负责为视图准备数据,或处理从视图而来的数据。表现 URL 是视图的事,与控制器无关,所以不要在控制器中生成 URL)

                为了实现高亮显示当前分类,设计 “Menu” 方法带有 “(string category = null)” 的参数

            (2)使用 Html.Action 辅助器方法把动作方法 “Menu” 的输出注入到布局之中

                在布局页中使用 @Html.Action("Menu", "Nav") 将分类导航菜单添加到布局页中

            (3)创建分部视图 Menu.cshtml

                右击 View Nav 文件夹,选择 “添加 MVC5 视图页面(Razor)”,设置其名称为 “Menu”,单击确定按钮。最后,先删除新视图中的默认内容。然后修改视图内容。

        4、修正页面计数

            在选中分类时页面链接的总数由被选中分类中的产品数所确定。

            通过更新 Product 控制器中的 List 动作方法,可以对此加以修改,以使分页信息把分类考虑进来。(在下一篇随笔中已经写好了)

      8.2 创建购物车

        1、定义购物车实体

            购物车是业务域的一部分,因此,在域模型中创建一个表现购物车的实体是有意义的。

            在 XXX.Domain 项目的 Entities 文件夹中添加一个名为 “Cart.cs” 的类文件。

        2、添加 “加入购物车” 按钮。

            需要修改分部视图 Views / Shared / ProductSummary.cshtml ,以将这些按钮添加到产品列表。

            添加一个 Razor 代码块,为列表中的每一个产品创建一个小型的 HTML表单。当该表单被递交时,将调用 Cart 控制器中的 AddToCart 动作方法。

        3、实现购物车控制器

            此时需要一个控制器来处理 “加入购物车” 按钮的单击。

            为此,在 XXX.WebUI 项目中创建一个新的控制器,名称为 “CartController” ,并编辑其内容。

            为了存储和接收Cart对象,这里使用了 ASP.NET 的会话状态特性。(没有保存到数据库,所以持久性不够这种方式可以用来保存用户id等信息

            ASP.NET 有一个很好的会话特性,它使用重写 cookies 或 URL 的办法,将一个用户的多个请求关联在一起,形成一个单一的浏览会话

            与之有关的一个特性是会话状态,它可以将数据与会话关联起来,这对 Cart 类(临时保存数据)很合适。(笔者希望每个用户有自己的购物车,并且希望购物车在各次请求之间是保持有效的)

            为了给会话状态添加一个对象,只要为 Session 对象上设置一个键的值即可,像这样:  Session["Cart"] = cart;

            要再次接收一个对象,只要简单地读取同一个键即可,像这样:  Cart  cart = (Cart)Session["Cart"];

            会话状态对象(Session对象)默认存储在 ASP.NET 服务器的内存中,但你可以配置不同的存储方式,包括使用一个 SQL 数据库。

        4、显示购物车内容

            本小节用 Index 方法来显示 Cart(购物车)的内容。

            笔者需要将两个数据片段传递给显示购物车:Cart 对象,以及用户点击“继续购物”按钮时要显示的 URL。(为此,在 XXX.WebUI 项目的 Models 文件夹中创建类文件 “CartIndexViewModel.cs”)

            显示购物车内容的最后一步是创建这个新视图 “Index.cshtml”

  • 相关阅读:
    lucene教程【转】【补】
    线程本地变量ThreadLocal (耗时工具)【原】
    Exception异常转String【转】
    织梦DedeCms网站更换域名后文章图片路径批量修改
    织梦DedeCms去掉栏目页面包屑导航最后的分隔符“>”
    dedecms网站栏目增加缩略图的方法-测试通过
    织梦dedecms调用子栏目的方法
    织梦DedeCMS调用二级子栏目或者多级栏目解决方法
    dedecms首页调用栏目内容和单页内容的方法
    JS中的prototype
  • 原文地址:https://www.cnblogs.com/zhangchaoran/p/7765243.html
Copyright © 2011-2022 走看看