Cleaning things up and getting add item to cart working for anonymous or authenticated users.

This commit is contained in:
Steve Smith
2017-07-24 16:45:54 -04:00
parent fb95b37da8
commit 925ad6b557
13 changed files with 182 additions and 54 deletions

View File

@@ -1,10 +0,0 @@
using System.Security.Claims;
namespace ApplicationCore.Entities
{
public class ApplicationUser : ClaimsIdentity
{
public string UserId { get; set; }
public string UserName { get; set; }
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.eShopWeb.ApplicationCore.Entities
{
@@ -6,5 +7,21 @@ namespace Microsoft.eShopWeb.ApplicationCore.Entities
{
public string BuyerId { get; set; }
public List<BasketItem> Items { get; set; } = new List<BasketItem>();
public void AddItem(int productId, decimal unitPrice, int quantity = 1)
{
if(!Items.Any(i => i.ProductId == productId))
{
Items.Add(new BasketItem()
{
ProductId = productId,
Quantity = quantity,
UnitPrice = unitPrice
});
return;
}
var existingItem = Items.FirstOrDefault(i => i.ProductId == productId);
existingItem.Quantity += quantity;
}
}
}

View File

@@ -1,17 +1,13 @@
using ApplicationCore.Entities;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System.Security.Principal;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System.Threading.Tasks;
namespace ApplicationCore.Interfaces
{
public interface IBasketService
{
Task<Basket> GetBasket(ApplicationUser user);
}
public interface IIdentityParser<T>
{
T Parse(IPrincipal principal);
Task<Basket> GetBasket(string basketId);
Task<Basket> CreateBasket();
Task<Basket> CreateBasketForUser(string userId);
Task UpdateBasket(Basket basket);
}
}

View File

@@ -0,0 +1,9 @@
using System.Security.Principal;
namespace ApplicationCore.Interfaces
{
public interface IIdentityParser<T>
{
T Parse(IPrincipal principal);
}
}

View File

@@ -20,8 +20,4 @@ namespace Infrastructure.Identity
}
}
public class ApplicationUser : IdentityUser
{
}
}

View File

@@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace Infrastructure.Identity
{
public class ApplicationUser : IdentityUser
{
}
}

View File

@@ -1,53 +1,64 @@
using Microsoft.eShopWeb.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using ApplicationCore.Interfaces;
using ApplicationCore.Entities;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using System;
using Microsoft.AspNetCore.Http;
namespace Microsoft.eShopWeb.Controllers
{
public class CartController : Controller
{
private readonly ICatalogService _catalogSvc;
private readonly IBasketService _basketSvc;
private readonly IIdentityParser<ApplicationUser> _appUserParser;
private readonly IBasketService _basketService;
//private readonly IIdentityParser<ApplicationUser> _appUserParser;
private const string _basketSessionKey = "basketId";
public CartController(IBasketService basketSvc,
IIdentityParser<ApplicationUser> appUserParser)
public CartController(IBasketService basketService)
// IIdentityParser<ApplicationUser> appUserParser)
{
//_catalogSvc = catalogSvc;
_basketSvc = basketSvc;
_appUserParser = appUserParser;
_basketService = basketService;
// _appUserParser = appUserParser;
}
// GET: /<controller>/
public async Task<IActionResult> Index()
{
var user = _appUserParser.Parse(HttpContext.User);
var viewmodel = await _basketSvc.GetBasket(user);
//var user = _appUserParser.Parse(HttpContext.User);
var basket = await GetBasketFromSessionAsync();
return View(viewmodel);
return View(basket);
}
public async Task<IActionResult> AddToCart(CatalogItem productDetails)
{
if (productDetails.Id != null)
if (productDetails?.Id == null)
{
var user = _appUserParser.Parse(HttpContext.User);
var product = new BasketItem()
{
Id = Guid.NewGuid().ToString(),
Quantity = 1,
UnitPrice = productDetails.Price,
ProductId = productDetails.Id
};
//await _basketSvc.AddItemToBasket(user, product);
}
return RedirectToAction("Index", "Catalog");
}
var basket = await GetBasketFromSessionAsync();
basket.AddItem(productDetails.Id, productDetails.Price, 1);
await _basketService.UpdateBasket(basket);
return RedirectToAction("Index");
}
private async Task<Basket> GetBasketFromSessionAsync()
{
string basketId = HttpContext.Session.GetString(_basketSessionKey);
Basket basket = null;
if (basketId == null)
{
basket = await _basketService.CreateBasketForUser(User.Identity.Name);
HttpContext.Session.SetString(_basketSessionKey, basket.Id);
}
else
{
basket = await _basketService.GetBasket(basketId);
}
return basket;
}
}
}

View File

@@ -10,6 +10,7 @@ namespace Microsoft.eShopWeb.Infrastructure
public CatalogContext(DbContextOptions<CatalogContext> options) : base(options)
{
}
public DbSet<Basket> Baskets { get; set; }
public DbSet<CatalogItem> CatalogItems { get; set; }
public DbSet<CatalogBrand> CatalogBrands { get; set; }
public DbSet<CatalogType> CatalogTypes { get; set; }

View File

@@ -0,0 +1,53 @@
using ApplicationCore.Interfaces;
using System.Threading.Tasks;
using Microsoft.eShopWeb.ApplicationCore.Entities;
using Microsoft.eShopWeb.Infrastructure;
using Microsoft.EntityFrameworkCore;
namespace Web.Services
{
public class BasketService : IBasketService
{
private readonly CatalogContext _context;
public BasketService(CatalogContext context)
{
_context = context;
}
public async Task<Basket> GetBasket(string basketId)
{
var basket = await _context.Baskets
.Include(b => b.Items)
.FirstOrDefaultAsync(b => b.Id == basketId);
if (basket == null)
{
basket = new Basket();
_context.Baskets.Add(basket);
await _context.SaveChangesAsync();
}
return basket;
}
public Task<Basket> CreateBasket()
{
return CreateBasketForUser(null);
}
public async Task<Basket> CreateBasketForUser(string userId)
{
var basket = new Basket();
_context.Baskets.Add(basket);
await _context.SaveChangesAsync();
return basket;
}
public async Task UpdateBasket(Basket basket)
{
// only need to save changes here
await _context.SaveChangesAsync();
}
}
}

View File

@@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Http;
using ApplicationCore.Interfaces;
using Infrastructure.FileSystem;
using Infrastructure.Logging;
using Web.Services;
namespace Microsoft.eShopWeb
{
@@ -41,8 +42,8 @@ namespace Microsoft.eShopWeb
{
try
{
//c.UseInMemoryDatabase("Catalog");
c.UseSqlServer(Configuration.GetConnectionString("CatalogConnection"));
c.UseInMemoryDatabase("Catalog");
//c.UseSqlServer(Configuration.GetConnectionString("CatalogConnection"));
c.ConfigureWarnings(wb =>
{
//By default, in this application, we don't want to have client evaluations
@@ -57,8 +58,8 @@ namespace Microsoft.eShopWeb
// Add Identity DbContext
services.AddDbContext<AppIdentityDbContext>(options =>
//options.UseInMemoryDatabase("Identity"));
options.UseSqlServer(Configuration.GetConnectionString("IdentityConnection")));
options.UseInMemoryDatabase("Identity"));
//options.UseSqlServer(Configuration.GetConnectionString("IdentityConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<AppIdentityDbContext>()
@@ -66,10 +67,19 @@ namespace Microsoft.eShopWeb
services.AddMemoryCache();
services.AddScoped<ICatalogService, CachedCatalogService>();
services.AddScoped<IBasketService, BasketService>();
services.AddScoped<CatalogService>();
services.Configure<CatalogSettings>(Configuration);
services.AddSingleton<IImageService, LocalFileImageService>();
services.AddScoped(typeof(IAppLogger<>), typeof(LoggerAdapter<>));
// Add memory cache services
services.AddMemoryCache();
// Add session related services.
services.AddSession();
services.AddMvc();
_services = services;
@@ -110,6 +120,8 @@ namespace Microsoft.eShopWeb
app.UseExceptionHandler("/Catalog/Error");
}
app.UseSession();
app.UseStaticFiles();
app.UseIdentity();

View File

@@ -0,0 +1,32 @@
@using Microsoft.eShopWeb.ApplicationCore.Entities;
@{
ViewData["Title"] = "Catalog";
@model Basket
}
<section class="esh-catalog-hero">
<div class="container">
<img class="esh-catalog-title" src="../images/main_banner_text.png" />
</div>
</section>
<div class="container">
@if (Model.Items.Any())
{
<div class="esh-catalog-items row">
@foreach (var item in Model.Items)
{
<div class="esh-catalog-item col-md-4">
@item.ProductId
</div>
}
</div>
}
else
{
<div class="esh-catalog-items row">
Cart is empty.
</div>
}
</div>

View File

@@ -4,7 +4,7 @@
<form asp-controller="Cart" asp-action="AddToCart">
<img class="esh-catalog-thumbnail" src="@Model.PictureUri" />
<input class="esh-catalog-button @((!User.Identity.IsAuthenticated) ? "is-disabled" : "")" type="submit" value="[ ADD TO CART ]" />
<input class="esh-catalog-button" type="submit" value="[ ADD TO CART ]" />
<div class="esh-catalog-name">
<span>@Model.Name</span>

View File

@@ -15,6 +15,7 @@
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Session" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="1.1.2" />