宝哥软件园

一步一步创建简单的MVC电商网站书店(1)

编辑:宝哥软件园 来源:互联网 时间:2021-09-05

一步一步创建一个简单的MVC电商网站——bookstore(上)

本系列的GitHub地址:https://github.com/liqingwen2015/Wen.书店

《一步步打造一个简单的 MVC 电商网站 - BooksStore(一)》

《一步步打造一个简单的 MVC 电商网站 - BooksStore(二)》

《一步步打造一个简单的 MVC 电商网站 - BooksStore(三)》

《一步步打造一个简单的 MVC 电商网站 - BooksStore(四)》

简介

主要功能和知识点如下:

分类、产品浏览、购物车、结算、CRUD管理、电子邮件、分页、模型绑定、认证过滤和单元测试等。(预计四篇,周五,下周一,周二)。

【备注】项目采用VS2015 C#6开发。请在留言区发表任何问题。另外,页面很丑。请原谅我。

目录

创建项目模式创建域模型实体创建单元测试创建控制器和视图创建分页连接样式一.创建项目模式

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

书店。领域:存储领域模型和逻辑并使用EF的类库;书店。webui: Web MVC应用,存储视图和控制器,充当显示层,使用Ninject作为DI容器;BoosStore。UnitTest:单元测试,对以上两项进行测试。

网络MVC是一个空的MVC项目:

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

这是不同项目需要参考的类库和项目

3.设置去离子容器

使用Ninject,我们创建了一个自定义工厂,一个名为NinjectControllerFactory的类继承了DefaultControllerFactory(默认控制器工厂)。您还可以添加自定义代码来更改MVC框架的默认行为。

AddBindings()添加一个绑定方法,并将其留空。

公共类ninejectcontrollerfactory : DefaultControllerFactory { private readonly IKernel _ kernel;public NinjectControllerFactory(){ _ kernel=new standard kernel();AddBindings();}受保护的覆盖图标控制器GetControllerInstance(RequestContext,request context,Type controller Type){ return controller Type==null?null : (IController) _kernel。get(controller type);}///summary///add bindings////summary private void add bindings(){ } } 4。并在Global.asax中添加一行代码,告诉MVC用新创建的类创建控制器对象。

ControllerBuilder。Current.SetControllerFactory(新的NinjectControllerFactory());

公共类MVC应用:系统。web . HttpApplication { protected void Application _ Start(){ area registration。registerelarias();路由图。注册路由(路由表。路线);ControllerBuilder。Current.SetControllerFactory(新的NinjectControllerFactory());第二,创建一个领域模型实体

1.在图中的位置创建一个名为Book的实体类。

公共类Book {///summary///Id///summary public int Id { get;设置;} ///summary ///name////summary公共字符串名称{ get设置;}///summary///description////summary公共字符串描述{ get设置;}///summary///price////summary public十进制价格{ get设置;} ///摘要///分类////摘要公共字符串类别{ get设置;}}有了实体之后,我们要创建一个“库”来操作实体,这个持久的逻辑操作要和域模型隔离开来。

2.首先定义一个接口IbookRepository,并在根目录下创建一个名为抽象的文件夹。顾名思义,应该放置一些抽象类,比如接口。

公共接口IBookRepository { iqueryablebookbooks { get;}}我们可以通过这个接口获取对应类的相关信息,而不必关心数据是如何存储的,存储在哪里,这就是存储库模式的本质。

3.接下来,我们需要操作数据库。我们使用简单的EF(ORM对象关系模型)来操作数据库,所以需要通过Nuget自己下载EF的类库。

4.因为接口类是之前定义的,所以接下来应该定义实现接口的类。

安装后,再次创建名为“混凝土”的文件夹来存储实例。

在其中创建一个从DbContext派生的EfDbContext类,这个类将自动为数据库中的每个表定义一个属性供用户使用。属性名是Books,它指定了表名。DbSetBook是Book实体的表模型,Book对象相当于Books表中的行(记录)。

公共类EfDbContext : DbContext { public DbSetBook Books { get;设置;}}创建另一个EfBookRepository repository类,它实现了IBookRepository接口,使用上面创建的EfDbContext上下文对象,并包含特定的方法定义。

公共类EfBookRepository : IBookRepository { private readonly EfDbContext _ context=new EfDbContext();public IQueryableBook Books=_ context。书籍;}5.现在我们只需要在数据库中创建一个新表。

创建一个表簿(id int identity主键,name nvarchar (100),description nvarchar (max),price decimal,category nvarchar (50))并插入测试数据:

插入dbo。书(名称、描述、价格、类别)值(n' c #从初学者到大师',- Name-nvarchar(100) N '好书-C#从初学者到大师',- Description - nvarchar(max),- Price -小数N '。NET' -类别- nvarchar(50))插入到dbo中。图书(名称,描述,价格,类别)价值(N'ASP.NET从入门到熟练',- Name-nvarchar(100) N '好书-ASP。NET从入门到熟练',-描述-nvarchar(最大值),-价格-小数n '。net'-category-nvarchar (50))插入dbo。图书(名称、描述、价格、类别)值(N '从初学者到大师的多线程',- Name-nvarchar(100) N '好书-从初学者到大师的多线程',- Description-nvarchar(max),-price-小数N '。net'-category-nvarchar (50))插入dbo.book(名称、描述、价格、类别)值(n' Java从入门到放弃',-Name-nvarchar(100)N ' good book-Java从入门到放弃',- Description-nvarchar(max),-price-小数n' Java'-category-nvarchar (50))插入dbo.book(名称、描述、价格、类别)值(n' SQL从入门到放弃',-Name-nvarchar(50书(名称、描述、价格、类别)值(n' SQL从初学者到出家',- Name-nvarchar(100) N '好书-sql从入门到出家',- Description-nvarchar(max),-price-十进制n' SQL'-category-nvarchar (50))插入dbo。书(名称、描述、价格、类别)值(n' PHP从入门到出家',-Name-nvarchar(100)N ' good book-PHP从初学者到出家',-description-nvarchar (max),-price-十进制n' PHP'-category-nvarchar (50))测试数据

因为我希望表名是Book,而不是Books,所以我在前一个Book类中添加了属性[table ('Book')]:

第三,创建单元测试

1.预热操作后,您可能想立即以界面的形式显示出来。不用担心,先用单元测试来检查我们对数据库的操作是否正常,简单的读取数据来检查连接是否成功。

2.单元测试还需要引入ef类库(Nuget)。

3.安装完成后,会生成一个app.config配置文件,需要额外添加一行连接字符串(这个信息需要在后续的Web UI项目中添加,否则会提示相应的错误信息)。

connectionStrings添加名称=' EfDbContext ' connectionString=' server='。数据库=TestDbuid=saPwd=123' providername='系统。data . sqlclient '/connection strings 4。当所有的前期工作都准备好了,就应该填写测试方法,因为我插入了7条数据,在这里我会判断从数据库中读取的行数是否为7:

[TestMethod]public void book count test(){ var book repository=new efbook repository();var books=bookRepository .书籍;断言。平等(书籍计数(),7);}5.在该方法体的内部单击右键,你可以看到一个"运行测试"的选项,这时你可以尝试单击它:

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

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

四、创建控制器与视图

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

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

公共类图书控制器:控制器{私有只读IBookRepository _ book repository;公共图书管理员(ibook repository图书仓库){ _ book repository=图书仓库;} ///摘要///详情////summary////returns/returns public action result Details(){ return View(_ book repository).书籍);} }3.接下来,要创建一个视图视角了。

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

@model IEnumerableWen .书店。领域。实体。book @ { viewpag .标题='书籍;}@foreach(模型中的定义变量项目){ h3@item.Name/h3分区@项目.描述h4@item .价格。ToString('C')/h4 br/hr//div}5 .改下默认的路由机制,让他默认跳转到该页面。

6.还有一点需要注意的是,因为我们使用了n项目容器,并且需要对控制器中的构造函数中的参数IBookRepository进行解析,告诉他将使用哪个对象对该接口进行服务,也就是需要修改之前的添加绑定方法:

7.运行的效果大致如下(因为加了点半铸钢钢性铸铁(铸造半钢)样式,所以显示的效果可能有些许不同),结果是一致的。

五、创建分页

1.在模型文件夹新增一个PagingInfo.cs分页信息类。

///摘要///分页信息////摘要公共类pagin info {///摘要///总数////summary public int TotaL tems { get;设置;} ///摘要///页容量////summary public int页面大小{ get设置;} ///摘要///当前页////summary public int page索引{ get设置;} ///摘要///总页数////summary public int TotalPages=(int)Math .上限((十进制)合计项目/页面大小);}2.新增一个HtmlHelpers文件夹存放一个基于超文本标记语言帮助类的扩展方法:

公共静态类PagingHelper { ///summary ///分页////summary////param name=' helper '/param///param name=' pagin info '/param///param name=' func '/param///returns/returns public static MvcHtmlString页面链接(此HtmlHelper、pagin info、pagin info、Funcint、string func){ var sb=new StringBuilder();for(var I=1;i=分页信息TotalPagesi ) { //创建a标签var标记生成器=新标记生成器(' a ');//添加特性标记构建器MergeAttribute('href ',func(I));//添加值标记构建器InnerHtml=I . ToString();if(I==pagin info .页面索引){标记构建器.addcsclass(' selected ');}某人。追加(标记生成器);}返回MvcHtmlString .创造(某人)ToString());} }3.添加完毕后需要在配置文件内加入该命名空间

4.现在要重新修改BookController.cs控制器内的的代码,并添加新的视图模型类BookDetailsViewModels.cs,让它继承之前的分页类。

公共类BookDetailsViewModels : pagin info { public IEnumerablebook { get;设置;} }修改后的控制器代码:

公共类图书控制器:控制器{私有只读IBookRepository _ book repository;public int page SiZe=5;公共图书管理员(ibook repository图书仓库){ _ book repository=图书仓库;} ///摘要///详情////summary////param name=' page index '/param////returns/returns public action result Details(int page index=1){ var model=new bookdetailsview models(){ Books=_ book repository .书籍。订单号(x=x.Id).跳过((页面索引- 1) *页面大小)。取(页面大小),页面大小=页面大小,页面索引=页面索引,合计项目=_bookRepository .书籍。count()};返回视图(模型);} }5.修改视图模型后,对应的视图页也需要修改

@模特文书店。webui。模特。bookdetailsviewmodels @ { view bag .标题='书籍;}@foreach(模型中的定义变量项。书籍){ h3@item.Name/h3分区@项目.描述h4 @项目.价格。ToString(' C ')/H4 br/HR//div } div class=' pager ' @ Html .页面链接(模型,x=Url .操作('详细信息,新的{页面索引=x })/div六、加入样式

1.页面的样式简单的设计为3大板块,顶部为标题,左侧边栏为分类,主模块将显示具体内容。

我们现在要在视图文件夹下创建一个文件_ViewStart.cshtml,再创建一个共享的的文件夹和文件_Layout.cshtml。

2._Layout.cshtml这是布局页,当代码执行到@RenderBody()时,就会负责将之前Details.cshtml的内容进行渲染:

!DOCTYPE htmlhtmlhead元名称=' viewport '内容=' width=设备宽度'/title@ViewBag.Title/title链接href='~/Contents/Site.css' rel='样式表/head dy div id=' head ' div class=' title '图书商城/div /div div id='侧栏'分类/div div id=' content ' @ render body()/div/body/html _ view start。cshtml该文件表示默认的布局页为该视图文件:

@ { Layout=' ~/view/Shared/_ Layout。“cshtml”;}3.网站的根目录下也要添加一个名为内容的文件夹,用于存放CSS。

正文{ } #标题,#内容,#侧边栏{ display : block } # header { background-color :绿色;边框-底部: 2px实心# 111;颜色:白色;} #标题,title { font-size : 1.5 empadding:5em } #侧边栏{左侧浮动:宽度: 8毫米;padding:3em } #内容{边框-左侧: 2px纯灰色;左边距: 10毫米;padding: 1em }。寻呼机{ text-align : right划水:5万;页边距-top : 1em;} .传呼机A { font-size : 1.1 em颜色: # 666划水0 .4em 0 .4em}。呼叫器A:hover {背景色-银色:} .寻呼机a .选中{底色: # 353535;颜色:白色;}

现在,分页也已经有了效果,基本界面就出来了。

本系列的开源代码库地址:https://github.com/liqingwen 2015/文.书店

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

更多资讯
游戏推荐
更多+