mirror of
https://github.com/rudollee/LearningMVC.git
synced 2025-07-03 20:56:23 +00:00
Ch. 8
SportsStore 2nd
This commit is contained in:
parent
0a9ec180c1
commit
5fff10e2a0
54
SportsStore.Domain/Entities/Cart.cs
Normal file
54
SportsStore.Domain/Entities/Cart.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
namespace SportsStore.Domain.Entities
|
||||||
|
{
|
||||||
|
public class Cart
|
||||||
|
{
|
||||||
|
private List<CartLine> lineCollection = new List<CartLine>();
|
||||||
|
|
||||||
|
public void AddItem(Product product, int quantity)
|
||||||
|
{
|
||||||
|
CartLine line = lineCollection
|
||||||
|
.Where(p => p.Product.ProductID == product.ProductID)
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (line == null)
|
||||||
|
{
|
||||||
|
lineCollection.Add(new CartLine { Product = product, Quantity = quantity });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
line.Quantity += quantity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveLine(Product product)
|
||||||
|
{
|
||||||
|
lineCollection.RemoveAll(l => l.Product.ProductID == product.ProductID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public decimal ComputeTotalValue()
|
||||||
|
{
|
||||||
|
return lineCollection.Sum(e => e.Product.Price * e.Quantity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
lineCollection.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<CartLine> Lines
|
||||||
|
{
|
||||||
|
get { return lineCollection; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CartLine
|
||||||
|
{
|
||||||
|
public Product Product { get; set; }
|
||||||
|
public int Quantity { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -108,6 +108,7 @@
|
|||||||
<Compile Include="Abstract\IProductRepository.cs" />
|
<Compile Include="Abstract\IProductRepository.cs" />
|
||||||
<Compile Include="Concrete\EFDbContext.cs" />
|
<Compile Include="Concrete\EFDbContext.cs" />
|
||||||
<Compile Include="Concrete\EFProductRepository.cs" />
|
<Compile Include="Concrete\EFProductRepository.cs" />
|
||||||
|
<Compile Include="Entities\Cart.cs" />
|
||||||
<Compile Include="Entities\Product.cs" />
|
<Compile Include="Entities\Product.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -9,21 +9,47 @@ namespace SportsStore.WebUI
|
|||||||
{
|
{
|
||||||
public class RouteConfig
|
public class RouteConfig
|
||||||
{
|
{
|
||||||
public static void RegisterRoutes(RouteCollection routes)
|
public static void RegisterRoutes(RouteCollection routes)
|
||||||
{
|
{
|
||||||
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
||||||
|
|
||||||
routes.MapRoute(
|
routes.MapRoute(null,
|
||||||
name: null,
|
"",
|
||||||
url: "Page{page}",
|
new {controller = "Product", action = "List", category = (string)null, page = 1 }
|
||||||
defaults: new { Controller = "Product", action = "List" }
|
|
||||||
);
|
);
|
||||||
|
|
||||||
routes.MapRoute(
|
routes.MapRoute(null,
|
||||||
name: "Default",
|
"page{page}",
|
||||||
url: "{controller}/{action}/{id}",
|
new { controller = "Product", action = "List", category = (string)null },
|
||||||
defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }
|
new { page = @"d+" }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//routes.MapRoute(
|
||||||
|
// name: null,
|
||||||
|
// url: "Page{page}",
|
||||||
|
// defaults: new { Controller = "Product", action = "List" }
|
||||||
|
//);
|
||||||
|
|
||||||
|
routes.MapRoute(
|
||||||
|
null,
|
||||||
|
"{category}",
|
||||||
|
new { controller = "Product", action = "List", page = 1 }
|
||||||
|
);
|
||||||
|
|
||||||
|
routes.MapRoute(
|
||||||
|
null,
|
||||||
|
"{category}/Page{page}",
|
||||||
|
new { controller = "Product", action = "List" },
|
||||||
|
new { page = @"\d+" }
|
||||||
|
);
|
||||||
|
|
||||||
|
//routes.MapRoute(
|
||||||
|
// name: "Default",
|
||||||
|
// url: "{controller}/{action}/{id}",
|
||||||
|
// defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }
|
||||||
|
//);
|
||||||
|
|
||||||
|
routes.MapRoute(null, "{controller}/{action}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
66
SportsStore.WebUI/Controllers/CartController.cs
Normal file
66
SportsStore.WebUI/Controllers/CartController.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using SportsStore.Domain.Abstract;
|
||||||
|
using SportsStore.Domain.Entities;
|
||||||
|
using SportsStore.WebUI.Models;
|
||||||
|
|
||||||
|
namespace SportsStore.WebUI.Controllers
|
||||||
|
{
|
||||||
|
public class CartController : Controller
|
||||||
|
{
|
||||||
|
private IProductRepository repository;
|
||||||
|
|
||||||
|
public CartController(IProductRepository repo)
|
||||||
|
{
|
||||||
|
repository = repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ViewResult Index(string returnUrl)
|
||||||
|
{
|
||||||
|
return View(new CartIndexViewModel { Cart = GetCart(), ReturnUrl = returnUrl });
|
||||||
|
}
|
||||||
|
|
||||||
|
public RedirectToRouteResult AddToCart(int productId, string returnUrl)
|
||||||
|
{
|
||||||
|
Product product = repository.Products
|
||||||
|
.FirstOrDefault(p => p.ProductID == productId);
|
||||||
|
|
||||||
|
if (product != null)
|
||||||
|
{
|
||||||
|
GetCart().AddItem(product, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RedirectToAction("Index", new { returnUrl });
|
||||||
|
}
|
||||||
|
|
||||||
|
public RedirectToRouteResult RemoveFromCart(int productId, string returnUrl)
|
||||||
|
{
|
||||||
|
Product product = repository.Products
|
||||||
|
.FirstOrDefault(p => p.ProductID == productId);
|
||||||
|
|
||||||
|
if (product != null)
|
||||||
|
{
|
||||||
|
GetCart().RemoveLine(product);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RedirectToAction("Index", new { returnUrl });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Cart GetCart()
|
||||||
|
{
|
||||||
|
Cart cart = (Cart)Session["Cart"];
|
||||||
|
if (cart == null)
|
||||||
|
{
|
||||||
|
cart = new Cart();
|
||||||
|
Session["Cart"] = cart;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cart;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
35
SportsStore.WebUI/Controllers/NavController.cs
Normal file
35
SportsStore.WebUI/Controllers/NavController.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using SportsStore.Domain.Abstract;
|
||||||
|
|
||||||
|
namespace SportsStore.WebUI.Controllers
|
||||||
|
{
|
||||||
|
public class NavController : Controller
|
||||||
|
{
|
||||||
|
private IProductRepository repository;
|
||||||
|
public NavController(IProductRepository repo)
|
||||||
|
{
|
||||||
|
repository = repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PartialViewResult Menu(string category = null)
|
||||||
|
{
|
||||||
|
ViewBag.SelectedCategory = category;
|
||||||
|
IEnumerable<string> categories = repository.Products
|
||||||
|
.Select(x => x.Category)
|
||||||
|
.Distinct()
|
||||||
|
.OrderBy(x => x);
|
||||||
|
|
||||||
|
return PartialView(categories);
|
||||||
|
}
|
||||||
|
|
||||||
|
//public string Menu()
|
||||||
|
//{
|
||||||
|
// return "Hello from NavController";
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@ namespace SportsStore.WebUI.Controllers
|
|||||||
// return View(repository.Products);
|
// return View(repository.Products);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public ViewResult List(int page = 1)
|
public ViewResult List(string category, int page = 1)
|
||||||
{
|
{
|
||||||
//return View(repository.Products
|
//return View(repository.Products
|
||||||
// .OrderBy(p => p.ProductID)
|
// .OrderBy(p => p.ProductID)
|
||||||
@ -34,6 +34,7 @@ namespace SportsStore.WebUI.Controllers
|
|||||||
ProductsListViewModel model = new ProductsListViewModel
|
ProductsListViewModel model = new ProductsListViewModel
|
||||||
{
|
{
|
||||||
Products = repository.Products
|
Products = repository.Products
|
||||||
|
.Where(p => category == null || p.Category == category)
|
||||||
.OrderBy(p => p.ProductID)
|
.OrderBy(p => p.ProductID)
|
||||||
.Skip((page - 1) * PageSize)
|
.Skip((page - 1) * PageSize)
|
||||||
.Take(PageSize),
|
.Take(PageSize),
|
||||||
@ -41,8 +42,12 @@ namespace SportsStore.WebUI.Controllers
|
|||||||
{
|
{
|
||||||
CurrentPage = page,
|
CurrentPage = page,
|
||||||
ItemsPerPage = PageSize,
|
ItemsPerPage = PageSize,
|
||||||
TotalItems = repository.Products.Count()
|
//TotalItems = repository.Products.Count()
|
||||||
}
|
TotalItems = category == null
|
||||||
|
? repository.Products.Count()
|
||||||
|
: repository.Products.Where(e => e.Category == category).Count()
|
||||||
|
},
|
||||||
|
CurrentCategory = category
|
||||||
};
|
};
|
||||||
|
|
||||||
return View(model);
|
return View(model);
|
||||||
|
14
SportsStore.WebUI/Models/CartIndexViewModel.cs
Normal file
14
SportsStore.WebUI/Models/CartIndexViewModel.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using SportsStore.Domain.Entities;
|
||||||
|
|
||||||
|
namespace SportsStore.WebUI.Models
|
||||||
|
{
|
||||||
|
public class CartIndexViewModel
|
||||||
|
{
|
||||||
|
public Cart Cart { get; set; }
|
||||||
|
public string ReturnUrl { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,8 @@ namespace SportsStore.WebUI.Models
|
|||||||
{
|
{
|
||||||
public IEnumerable<Product> Products { get; set; }
|
public IEnumerable<Product> Products { get; set; }
|
||||||
public PagingInfo PagingInfo { get; set; }
|
public PagingInfo PagingInfo { get; set; }
|
||||||
|
public string CurrentCategory { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -135,12 +135,15 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="App_Start\NinjectWebCommon.cs" />
|
<Compile Include="App_Start\NinjectWebCommon.cs" />
|
||||||
<Compile Include="App_Start\RouteConfig.cs" />
|
<Compile Include="App_Start\RouteConfig.cs" />
|
||||||
|
<Compile Include="Controllers\CartController.cs" />
|
||||||
|
<Compile Include="Controllers\NavController.cs" />
|
||||||
<Compile Include="Controllers\ProductController.cs" />
|
<Compile Include="Controllers\ProductController.cs" />
|
||||||
<Compile Include="Global.asax.cs">
|
<Compile Include="Global.asax.cs">
|
||||||
<DependentUpon>Global.asax</DependentUpon>
|
<DependentUpon>Global.asax</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="HtmlHelpers\PagingHelpers.cs" />
|
<Compile Include="HtmlHelpers\PagingHelpers.cs" />
|
||||||
<Compile Include="Infrastructure\NinjectDependencyResolver.cs" />
|
<Compile Include="Infrastructure\NinjectDependencyResolver.cs" />
|
||||||
|
<Compile Include="Models\CartIndexViewModel.cs" />
|
||||||
<Compile Include="Models\PagingInfo.cs" />
|
<Compile Include="Models\PagingInfo.cs" />
|
||||||
<Compile Include="Models\ProductsListViewModel.cs" />
|
<Compile Include="Models\ProductsListViewModel.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
@ -153,6 +156,8 @@
|
|||||||
<Content Include="Views\Product\List.cshtml" />
|
<Content Include="Views\Product\List.cshtml" />
|
||||||
<Content Include="Scripts\jquery-1.10.2.min.map" />
|
<Content Include="Scripts\jquery-1.10.2.min.map" />
|
||||||
<Content Include="Views\Shared\ProductSummary.cshtml" />
|
<Content Include="Views\Shared\ProductSummary.cshtml" />
|
||||||
|
<Content Include="Views\Nav\Menu.cshtml" />
|
||||||
|
<Content Include="Views\Cart\Index.cshtml" />
|
||||||
<None Include="Web.Debug.config">
|
<None Include="Web.Debug.config">
|
||||||
<DependentUpon>Web.config</DependentUpon>
|
<DependentUpon>Web.config</DependentUpon>
|
||||||
</None>
|
</None>
|
||||||
|
42
SportsStore.WebUI/Views/Cart/Index.cshtml
Normal file
42
SportsStore.WebUI/Views/Cart/Index.cshtml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
@model SportsStore.WebUI.Models.CartIndexViewModel
|
||||||
|
@{
|
||||||
|
ViewBag.Title = "Sports Store: Your Cart";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h2>Your cart</h2>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Quantity</th>
|
||||||
|
<th>Item</th>
|
||||||
|
<th class="text-right">Price</th>
|
||||||
|
<th class="text-right">Subtotal</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var line in Model.Cart.Lines)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td class="text-center">@line.Quantity</td>
|
||||||
|
<td class="text-left">@line.Product.Name</td>
|
||||||
|
<td class="text-right">@line.Product.Price.ToString("c")</td>
|
||||||
|
<td class="text-right">
|
||||||
|
@((line.Quantity * line.Product.Price).ToString("c"))
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="text-right">Total:</td>
|
||||||
|
<td class="text-right">
|
||||||
|
@Model.Cart.ComputeTotalValue().ToString("c")
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="btn btn-primary" href="@Model.ReturnUrl">Continue Shopping</a>
|
||||||
|
</div>
|
||||||
|
|
13
SportsStore.WebUI/Views/Nav/Menu.cshtml
Normal file
13
SportsStore.WebUI/Views/Nav/Menu.cshtml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
@model IEnumerable<string>
|
||||||
|
|
||||||
|
@Html.ActionLink("Home", "List", "Product", null,
|
||||||
|
new { @class = "btn btn-block btn-default btn-lg" })
|
||||||
|
|
||||||
|
@foreach (var link in Model)
|
||||||
|
{
|
||||||
|
@Html.RouteLink(
|
||||||
|
link,
|
||||||
|
new { controller = "Product", action = "List", category = link, page = 1 },
|
||||||
|
new { @class = "btn btn-block btn-default btn-lg" + (link == ViewBag.SelectedCategory ? " btn-primary" : "") }
|
||||||
|
)
|
||||||
|
}
|
@ -10,5 +10,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x}))
|
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x, category = Model.CurrentCategory}))
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,5 +5,13 @@
|
|||||||
<strong>@Model.Name</strong>
|
<strong>@Model.Name</strong>
|
||||||
<span class="pull-right label label-primary">@Model.Price</span>
|
<span class="pull-right label label-primary">@Model.Price</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
@using (Html.BeginForm("AddToCart", "Cart"))
|
||||||
|
{
|
||||||
|
<div class="pull-right">
|
||||||
|
@Html.HiddenFor(x => x.ProductID)
|
||||||
|
@Html.Hidden("returnUrl", Request.Url.PathAndQuery)
|
||||||
|
<input type="submit" class="btn btn-success" value="Add to cart" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<span class="lead"> @Model.Description</span>
|
<span class="lead"> @Model.Description</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row panel">
|
<div class="row panel">
|
||||||
<div id="categories" class="col-xs-3">
|
<div id="categories" class="col-xs-3">
|
||||||
Put something useful here later
|
@Html.Action("Menu", "Nav")
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-8">
|
<div class="col-xs-8">
|
||||||
@RenderBody()
|
@RenderBody()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user