首页 > 代码库 > [.NET] 一步步打造一个简单的 MVC 网站 - BooksStore

[.NET] 一步步打造一个简单的 MVC 网站 - BooksStore

一步步打造一个简单的 MVC 网站 - BooksStore

简介

  主要功能与知识点如下:

    分类、产品浏览、购物车、结算、CRUD(增删改查) 管理、分页和单元测试。

     【备注】项目使用 VS2015 + C#6 进行开发。

 

一、创建项目架构

  1.新建一个解决方案“BooksStore”,并添加以下项目:

技术分享

  

     BooksStore.Domain:类库,存放域模型和逻辑,使用 EF;
     BooksStore.WebUI:Web 应用程序,存放视图和控制器,充当显示层;
     BoosStore.UnitTest:单元测试,对上述两个项目进行测试。

  

  Web MVC 为一个空的 MVC 项目:

技术分享

 

  2.添加项目引用(需要使用 NuGet):

技术分享  技术分享  技术分享

  这是不同项目需要引用的类库和项目

 

  3.设置 DI 容器
     我们通过 Ninject ,创建一个名为 NinjectControllerFactory 的类继承 DefaultControllerFactory(默认的控制器工厂)
 技术分享

 

    public class NinjectControllerFactory : DefaultControllerFactory    {        private readonly IKernel _kernel;        public NinjectControllerFactory()        {            _kernel = new StandardKernel();            AddBindings();        }        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)        {            return controllerType == null                ? null                : (IController) _kernel.Get(controllerType);        }        /// <summary>        /// 添加绑定        /// </summary>        private void AddBindings()        {                    }    }

 

   并且在 Global.asax 中加入一行代码,告诉 MVC 用新建的类来创建控制器对象
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
技术分享
    public class MvcApplication : System.Web.HttpApplication    {        protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();            RouteConfig.RegisterRoutes(RouteTable.Routes);            ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());        }    }
Global.asax

 

二、创建域模型实体

技术分享

     在图中位置创建一个名为 Book 的实体类。
    public class Book    {        /// <summary>        /// 标识        /// </summary>        public int Id { get; set; }        /// <summary>        /// 名称        /// </summary>        public string Name { get; set; }        /// <summary>        /// 描述        /// </summary>        public string Description { get; set; }        /// <summary>        /// 价格        /// </summary>        public decimal Price { get; set; }        /// <summary>        /// 分类        /// </summary>        public string Category { get; set; }    }

     

  有了实体之后,我们应该创建一个“库”对该实体进行操作,而这种持久化操作也应该和域模型是进行隔离的,这种操作可以称为存储库模式。

     然后,在根目录创建一个名为 Abstract 的文件夹,顾名思义就是应该放置一些抽象的类,如接口,我们先定义一个对 Book 存储库进行操作的接口:

技术分享

    public interface IBookRepository    {        IQueryable<Book> Books { get; }    }

 

  在这里,我打算使用简单的 EF 去对数据库进行操作,所以需要自己通过 Nuget 下载 EF 的类库。

技术分享

 

  因为之前定义了接口类,接下来就应该定义实现该接口的类了

技术分享

 

    public class EfDbContext : DbContext    {        public DbSet<Book> Books { get; set; }    }

 

    public class EfBookRepository : IBookRepository    {        private readonly EfDbContext _context = new EfDbContext();        public IQueryable<Book> Books => _context.Books;    }

 

   现在只差在数据库新建一张表了。

CREATE TABLE Book(     Id INT IDENTITY PRIMARY KEY,     Name NVARCHAR(100),     Description NVARCHAR(MAX),     Price DECIMAL,     Category NVARCHAR(50))

   并插入测试数据:

技术分享
INSERT INTO dbo.Book        (           Name ,          Description ,          Price ,          Category        )VALUES  (           NC#从入门到精通 , -- Name - nvarchar(100)          N好书-C#从入门到精通 , -- Description - nvarchar(max)          50 , -- Price - decimal          N.NET  -- Category - nvarchar(50)        )INSERT INTO dbo.Book        (           Name ,          Description ,          Price ,          Category        )VALUES  (           NASP.NET从入门到精通 , -- Name - nvarchar(100)          N好书-ASP.NET从入门到精通 , -- Description - nvarchar(max)          60 , -- Price - decimal          N.NET  -- Category - nvarchar(50)        )INSERT INTO dbo.Book        (           Name ,          Description ,          Price ,          Category        )VALUES  (           N多线程从入门到精通 , -- Name - nvarchar(100)          N好书-多线程从入门到精通 , -- Description - nvarchar(max)          65 , -- Price - decimal          N.NET  -- Category - nvarchar(50)        )INSERT INTO dbo.Book        (           Name ,          Description ,          Price ,          Category        )VALUES  (           Njava从入门到放弃 , -- Name - nvarchar(100)          N好书-java从入门到放弃 , -- Description - nvarchar(max)          65 , -- Price - decimal          Njava  -- Category - nvarchar(50)        )INSERT INTO dbo.Book        (           Name ,          Description ,          Price ,          Category        )VALUES  (           Nsql从入门到放弃 , -- Name - nvarchar(100)          N好书-sql从入门到放弃 , -- Description - nvarchar(max)          45 , -- Price - decimal          Nsql  -- Category - nvarchar(50)        )INSERT INTO dbo.Book        (           Name ,          Description ,          Price ,          Category        )VALUES  (           Nsql从入门到出家 , -- Name - nvarchar(100)          N好书-sql从入门到出家 , -- Description - nvarchar(max)          45 , -- Price - decimal          Nsql  -- Category - nvarchar(50)        )INSERT INTO dbo.Book        (           Name ,          Description ,          Price ,          Category        )VALUES  (           Nphp从入门到出家 , -- Name - nvarchar(100)          N好书-php从入门到出家 , -- Description - nvarchar(max)          45 , -- Price - decimal          Nphp  -- Category - nvarchar(50)        )
测试数据

技术分享

 

三、单元测试

  做完预热操作后,你可能想立即以界面的的方式进行显示,别急,先用单元测试检查一下我们对数据库的操作是否正常,通过对数据进行简单的读取,检查下连接是否成功。

技术分享

  

  单元测试也需要引入 ef 类库(Nuget)

  安装完之后会生成一个 app.config 配置文件,需要额外添加一行连接字符串。

  <connectionStrings>    <add name="EfDbContext" connectionString="server=.;database=TestDb;uid=sa;pwd=123" providerName="System.Data.SqlClient"/>  </connectionStrings>

 

   当所有前置工作都准备好了的时候,就应该填写测试方法了:

        [TestMethod]        public void BooksCountTest()        {            var bookRepository=new EfBookRepository();            var books = bookRepository.Books;            Assert.AreEqual(books.Count(),7);        }

  

  在该方法体的内部单击右键,你可以看到一个“运行测试”的选项,这时你可以尝试单击它:

技术分享

技术分享

   从这个符号可以看到,是成功了!

  接下来,我们要正式从页面显示我们想要的信息了。

 

 

四、控制器与视图 

  先新建一个空的控制器:BookController:

技术分享

 

  需要我们自定义一个 Details 方法,用于后续与界面进行交互。

    public class BookController : Controller    {        private readonly IBookRepository _bookRepository;        public BookController(IBookRepository bookRepository)        {            _bookRepository = bookRepository;        }        /// <summary>        /// 详情        /// </summary>        /// <returns></returns>        public ActionResult Details()        {            return View(_bookRepository.Books);        }    }

 

  接下来,要创建一个视图 View 了。

技术分享

 

  将 Details.cshtml 的内容替换为下面的:

@model IEnumerable<Wen.BooksStore.Domain.Entities.Book>@{    ViewBag.Title = "Books";}@foreach (var item in Model){    <div>        <h3>@item.Name</h3>        @item.Description        <h4>@item.Price.ToString("C")</h4>        <br />        <hr />    </div>}

 

  改下默认的路由机制,让他默认跳转到该页面。

技术分享

  运行的效果大致如下(因为加了点 CSS 样式,所以显示的效果可能有些许不同),结果是一致的。

技术分享

 

五、分页

 

【博主】反骨仔

【原文】http://www.cnblogs.com/liqingwen/p/6640861.html

[.NET] 一步步打造一个简单的 MVC 网站 - BooksStore