SportsStore(一个体育商店MVC程序(1))

  这是我注册博客园的第一片文章,我想写一下自己最近学习MVC3所看的一本书《Pro.ASP.NET.MVC.3》中所讲的一个SportsStore的例子,这个例子分了很多章来完善SportsStore的不同功能,所以这个系列的文章也会按功能的实现分为很多篇。

  本文对原程序有一定的改动,省去了原程序中测试和依赖注入的部分

  实现数据的显示

  程序构建

  首先,创建一个空白的解决方案,起名为SportsStore

  

 添加完空白的解决方案以后,我们就要开始完成我们的程序了。我们需要添加如下的两个项目到我们的解决方案中:


  项目名                          项目在VS中的项目类型                                作  用


 SportsStore.Domain                         类库                               保存域实体和逻辑,通过用Entity
                                                                   Framework生成的存储库保持联系

 

   SportsStore.WebUI                   ASP.NET MVC 3 应用程序                         保存controller和view,担当程序的UI


添加好后的解决方案如下图:为了方便测试,右键单击SportsStore.WebUI 将它设为启动项

Model

添加域模型:在 SportsStore.Domain下新建一个名为Entities的文件夹,添加一个名为Product的类如下图:

 1 namespace SportsStore.Domain.Entities { 
 2  
 3     public class Product { 
 4         public int ProductID { get; set; } 
 5         public string Name { get; set; } 
 6         public string Description { get; set; } 
 7         public decimal Price { get; set; } 
 8         public string Category { get; set; } 
 9     } 
10 } 

在SportsStore.WebUI的Model文件夹下添加类StoreDbContext

1 namespace SportsStore.WebUI.Models
2 {
3     public class StoreDbContext:DbContext
4     {
5         public DbSet<Product> Products { get; set; }
6     }
7 }

 

在SportsStore.WebUI的Web.config里的<configuration>标签下添加

1   <connectionStrings>
2     <add name="StoreDbContext" connectionString="这里添加你的数据库地址" providerName="System.Data.SqlClient"/>
3   </connectionStrings>

Controller

  添加一个空的ProductController到SportsStore.WebUI的Controller文件夹下

     对新添加的ProductController代码进行修改,如下:

public class ProductController : Controller
    {
        StoreDbContext db = new StoreDbContext();
        public ActionResult List()
        {
            var product = db.Products;
            return View(product);
        }

    }

View

  在View下新建名为Product的文件夹,添加名为List的View

 图中红框标注的为要注意的地方

修改List的代码如下:

 1 @model IEnumerable<SprotsStore.Domain.Entities.Product>
 2 
 3 @{
 4     ViewBag.Title = "List";
 5 }
 6 
 7 <h2>List</h2>
 8 
 9 @foreach (var p in Model)
10 { 
11     <div class="item"> 
12     <h3>@p.Name</h3> 
13         @p.Description 
14     <h4>@p.Price.ToString("c")</h4> 
15 </div>
16 }

Routing

  这时启动项目还是会报错的,我们需要将原文中的Golbal.asax中的代码

 

 new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults

 

 改为

  new { controller = "Product", action = "List", id = UrlParameter.Optional } // Parameter defaults

这样系统就能找到我们所添加的LIst.cshtml了,然后启动程序

如图就是我们的体育用品商店显示的商品列表(事先添加了数据到数据库里)。

  

很不好看对不对,照这么列下去,我们的页面会被拉得很长很长,所以我们现在要添加一个为我们的体育用品商店添加一个分页的功能。

实现数据的分页显示

       Controller

  修改ProductController下的List(),使他能够根据分页信息返回相应的数据。

 1     public class ProductController : Controller
 2     {
 3         StoreDbContext db = new StoreDbContext();
 4         public int PageSize = 4; //定义每页显示4条数据
 5         public ActionResult List(int page=1)
 6         {
 7             //根据ProductID排序,略过(page-1)*4条数据,查找4条数据
 8             var product = db.Products.OrderBy(p => p.ProductID).Skip((page - 1) * PageSize).Take(PageSize);
 9             return View(product);
10         }
11     }

 

         这时你启动程序的话,只能看到页面显示了4条数据。你可以通过在链接地址后加参数的方式来查看后面的数据http://localhost:3719/?page=2,要看第几页的数据,将page的值改为几就可以了。这样我们的程序就实现了分页显示的功能了,但是客户来到你的商店,他们可不知道你的商店的数据显示需要这么操作滴。所以,为他们添加显式的分页操作按钮就变得非常有必要。下面,我们就来添加显式的分页信息。

  Model

        为Models文件夹添加一个名为PagingInfo的类,他包含了分页所需的数据信息,如下:

 1  public class PagingInfo
 2     {
 3        //总共有多少条数据
 4         public int TotalItems { get; set; }
 5         //每页几条数据
 6         public int ItemsPerPage { get; set; }
 7         //当前页是第几页
 8         public int CurrentPage { get; set; }
 9         //总共多少页
10         public int TotalPages
11         {
12             get { return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); }
13         } 
14     }

      PagingHelpers

       添加了分页信息的类PagingInfo后,我们需要考虑的是如何根据分页信息传回的数据来动态生成相应的页数信息来显示到页面上呢?比如一共10条数据,每页显示两条我们就需要分5页显示,要是每页显示5条的话,那只需显示两页就好了。

       在 SportsStore.WebUI 下创建一个名为HtmlHelpers的文件夹,并新建一个名为PagingHelpers的静态类,他将作为HtmlHelper的扩展方法存在。在页面中用@Html.来调用。PagingHelpers的内容如下:

 1  public static class PagingHelpers
 2     {
 3         public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func<int, string> pageUrl)
 4         {
 5             //新建StringBuilder实例result 将他作为最终的html字符串 生成相应的 标签 
 6             StringBuilder result = new StringBuilder();
 7             //循环遍历pagingInfo.TotalPages 生成相应个数的分页数字:1,2,3....
 8             for (int i = 1; i <= pagingInfo.TotalPages; i++)
 9             {
10                 //使用TagBuilder创建a标签
11                 TagBuilder tag = new TagBuilder("a");
12 
13                 //当前a标签的跳转地址
14                 tag.MergeAttribute("href", pageUrl(i));
15                 //以数字代表a标签的显示内容
16                 tag.InnerHtml = i.ToString();
17 
18 
19                 if (i == pagingInfo.CurrentPage)
20                     tag.AddCssClass("selected");
21 
22                 result.Append(tag.ToString());
23             }
24 
25             return MvcHtmlString.Create(result.ToString());
26         }
27     }

   现在就需要将我们的PageLinks添加到View的List.cshtml里去,但是直接添加的话会报错。

      无法找到PageLinks的引用,这中情况有两种解决方法。一种是将他的引用“@using SportsStore.WebUI.HtmlHelpers”添加到页面顶部,另一种是找到View文件夹下的Web.config,在<namespaces>下添加命名空间<add namespace="SportsStore.WebUI.HtmlHelpers"/>

     到这里我们的功能基本可以实现了,需要在做一下整合。

     Model :在model下添加一个名为ProductsListViewModel 的类将产品信息和分页信息结合在一起。

1  public class ProductsListViewModel { 
2  
3         public IEnumerable<Product> Products { get; set; } 
4         public PagingInfo PagingInfo { get; set; } 
5     } 

 

     Controller:修改ProductController下的List,将产品信息和分页信息同时返回个View

 1 public ViewResult List(int page = 1) { 
 2  
 3     ProductsListViewModel viewModel = new ProductsListViewModel { 
 4         Products = repository.Products 
 5             .OrderBy(p => p.ProductID) 
 6             .Skip((page - 1) * PageSize) 
 7             .Take(PageSize), 
 8         PagingInfo = new PagingInfo { 
 9             CurrentPage = page, 
10             ItemsPerPage = PageSize, 
11             TotalItems = repository.Products.Count() 
12         } 
13     }; 
14     return View(viewModel); 
15 }

     View:修改List.cshtml,通过ProductsListViewModel 获取产品信息和分页信息,添加PageLinks,在页面显示。

 1 @model SportsStore.WebUI.Models.ProductsListViewModel
 2 
 3 @{
 4     ViewBag.Title = "List";
 5 }
 6 
 7 <h2>List</h2>
 8 
 9 @foreach (var p in Model.Products)
10 { 
11     <div class="item"> 
12     <h3>@p.Name</h3> 
13         @p.Description 
14     <h4>@p.Price.ToString("c")</h4> 
15 </div>
16 }
17 <div class="pager"> 
18    @Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page = x})) 
19 </div>

如此,启动程序,可以看到我们的程序可以进行分页显示了

                           

遗留问题修改

  改善URL

                   

     如上图,这样的url和我们的路由选择并不相符,我们可以在Global.asax中添加一个新的路由,因为路由的选择是从上往下的,所以将以下的路由添加到第一位。

 routes.MapRoute(
            null,
           "Page{page}",
           new { Controller = "Product", action = "List" }
           ); 

 

   这样我们得到的url如下图    

    

         样式的添加

             我们的页面还需要添加一点样式

             对Views文件夹下的Shared文件夹下的_layout.cshtml的body标签进行如下修改:

1 <div id="header"> 
2         <div class="title">SPORTS STORE</div> 
3      </div> 
4      <div id="categories"> 
5         Will put something useful here later 
6      </div> 
7      <div id="content"> 
8         @RenderBody() 
9     </div> 

 

             为Content文件夹下的Site.css添加以下样式:

 1 BODY { font-family: Cambria, Georgia, "Times New Roman"; margin: 0; } 
 2 DIV#header DIV.title, DIV.item H3, DIV.item H4, DIV.pager A { 
 3     font: bold 1em "Arial Narrow", "Franklin Gothic Medium", Arial; 
 4 } 
 5 DIV#header { background-color: #444; border-bottom: 2px solid #111; color: White; } 
 6 DIV#header DIV.title { font-size: 2em; padding: .6em; } 
 7 DIV#content { border-left: 2px solid gray; margin-left: 9em; padding: 1em; } 
 8 DIV#categories { float: left; width: 8em; padding: .3em; } 
 9 DIV.item { border-top: 1px dotted gray; padding-top: .7em; margin-bottom: .7em; } 
10 DIV.item:first-child { border-top:none; padding-top: 0; } 
11 DIV.item H3 { font-size: 1.3em; margin: 0 0 .25em 0; } 
12 DIV.item H4 { font-size: 1.1em; margin:.4em 0 0 0; } 
13  
14 DIV.pager { text-align:right; border-top: 2px solid silver; 
15     padding: .5em 0 0 0; margin-top: 1em; } 
16 DIV.pager A { font-size: 1.1em; color: #666; text-decoration: none; 
17       padding: 0 .4em 0 .4em; } 
18 DIV.pager A:hover { background-color: Silver; } 
19 DIV.pager A.selected { background-color: #353535; color: White; }

           这样我们的体育用品商店就比以前要好看许多了。

      添加部分视图

            试想如果这些商品的信息我们需要在其他地方也可以重用,那我们该怎么做呢?是不是先要把他分离出来,这就需要我们为程序添加一个部分视图了。

            首先,右键单击Views文件夹下的Shared文件夹,添加一个View

            然后为这个View起名为ProductSummary,选择类型为Product,重要的是要勾选“Create as a partial view”选项。做完这三步,点击“Add”就好了。

           现在修改这个部分视图,如下:

 

1  <div class="item"> 
2     <h3>@Model.Name</h3> 
3         @Model.Description 
4     <h4>@Model.Price.ToString("c")</h4> 
5 </div>

 

           并对List.cshtml的foreach进行修改:

1 @foreach (var p in Model.Products)
2 {
3     Html.RenderPartial("ProductSummary", p); 
4 }

          好了,这下我们的数据就被分离出来了,以后在什么地方要用到这些商品数据的话,直接用以上代码来调用就好了,是不是很方便呢?

          这一章的内容到这里就结束了,来总结一下我们的成果吧!首先,我们实现商品数据的显示,然后发现浏览起来不是很方便,我们有为它添加了分页浏览的功能,穿插其中我们还完成了URL的优化、界面的美化等功能。这是我的第一篇博客,还有很多不足的地方需要完善,希望大家多提宝贵意见,我好不断改进,写出更好的博客来与大家分享!

转载于:https://www.cnblogs.com/feiDD/articles/2563014.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以给你一些指导。 首先,我们需要设计程序的界面。你可以使用 Python 的 Tkinter 模块或 PyQt5 模块来创建程序的 GUI 界面。 接下来,我们需要考虑程序MVC 架构。MVC 是一种常见的设计模式,它将程序分为三个主要部分:模型、视图和控制器。 - 模型:负责处理程序的数据,例如学生的姓名、年龄、性别、成绩等信息。你可以使用 Python 的面向对象编程来创建一个学生类,其中包含这些属性和方法。 - 视图:负责显示程序的用户界面。你可以使用 Tkinter 或 PyQt5 模块来创建用户界面,并将它们与模型和控制器连接起来。 - 控制器:负责处理程序的逻辑,例如添加、删除或更新学生信息。你可以使用 Python 的函数来实现控制器。 下面是一个简单的示例代码,帮助你更好地理解 MVC 架构: ```python # model.py class Student: def __init__(self, name, age, gender, score): self.name = name self.age = age self.gender = gender self.score = score # view.py class StudentView: def show_student(self, student): print(f"Name: {student.name}") print(f"Age: {student.age}") print(f"Gender: {student.gender}") print(f"Score: {student.score}") # controller.py class StudentController: def __init__(self, model, view): self.model = model self.view = view def set_name(self, name): self.model.name = name def set_age(self, age): self.model.age = age def set_gender(self, gender): self.model.gender = gender def set_score(self, score): self.model.score = score def update_view(self): self.view.show_student(self.model) # main.py from model import Student from view import StudentView from controller import StudentController student = Student("Tom", 18, "male", 90) view = StudentView() controller = StudentController(student, view) controller.update_view() controller.set_name("Jerry") controller.set_score(80) controller.update_view() ``` 在此示例中,我们创建了一个名为 Student 的模型类,一个名为 StudentView 的视图类和一个名为 StudentController 的控制器类。我们还编写了一个名为 main.py 的主程序用于演示如何使用 MVC 架构来管理学生信息。 接下来,你可以使用 Tkinter 或 PyQt5 模块来创建 GUI 界面,并将其与模型和控制器连接起来。例如,你可以创建一个名为 StudentGUI 的类,用于显示学生信息,并使用 StudentController 类来处理用户输入和更新学生信息。 希望这些指导对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值