Basket : Improve, reduce, remove duplication call to database (#610)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.eShopWeb.Web.Pages.Basket;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate;
|
||||
using Microsoft.eShopWeb.Web.Pages.Basket;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopWeb.Web.Interfaces
|
||||
@@ -6,5 +7,9 @@ namespace Microsoft.eShopWeb.Web.Interfaces
|
||||
public interface IBasketViewModelService
|
||||
{
|
||||
Task<BasketViewModel> GetOrCreateBasketForUser(string userName);
|
||||
|
||||
Task<int> CountTotalBasketItems(string username);
|
||||
|
||||
Task<BasketViewModel> Map(Basket basket);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.eShopWeb.ApplicationCore.Interfaces;
|
||||
using Microsoft.eShopWeb.Infrastructure.Identity;
|
||||
using Microsoft.eShopWeb.Web.Interfaces;
|
||||
using Microsoft.eShopWeb.Web.ViewModels;
|
||||
using System;
|
||||
@@ -16,16 +14,12 @@ namespace Microsoft.eShopWeb.Web.Pages.Basket
|
||||
public class IndexModel : PageModel
|
||||
{
|
||||
private readonly IBasketService _basketService;
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
private string _username = null;
|
||||
private readonly IBasketViewModelService _basketViewModelService;
|
||||
|
||||
public IndexModel(IBasketService basketService,
|
||||
IBasketViewModelService basketViewModelService,
|
||||
SignInManager<ApplicationUser> signInManager)
|
||||
IBasketViewModelService basketViewModelService)
|
||||
{
|
||||
_basketService = basketService;
|
||||
_signInManager = signInManager;
|
||||
_basketViewModelService = basketViewModelService;
|
||||
}
|
||||
|
||||
@@ -33,7 +27,7 @@ namespace Microsoft.eShopWeb.Web.Pages.Basket
|
||||
|
||||
public async Task OnGet()
|
||||
{
|
||||
await SetBasketModelAsync();
|
||||
BasketModel = await _basketViewModelService.GetOrCreateBasketForUser(GetOrSetBasketCookieAndUserName());
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPost(CatalogItemViewModel productDetails)
|
||||
@@ -42,64 +36,58 @@ namespace Microsoft.eShopWeb.Web.Pages.Basket
|
||||
{
|
||||
return RedirectToPage("/Index");
|
||||
}
|
||||
await SetBasketModelAsync();
|
||||
|
||||
await _basketService.AddItemToBasket(BasketModel.Id, productDetails.Id, productDetails.Price);
|
||||
var username = GetOrSetBasketCookieAndUserName();
|
||||
var basket = await _basketService.AddItemToBasket(username,
|
||||
productDetails.Id, productDetails.Price);
|
||||
|
||||
await SetBasketModelAsync();
|
||||
BasketModel = await _basketViewModelService.Map(basket);
|
||||
|
||||
return RedirectToPage();
|
||||
}
|
||||
|
||||
public async Task OnPostUpdate(IEnumerable<BasketItemViewModel> items)
|
||||
{
|
||||
await SetBasketModelAsync();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var basketView = await _basketViewModelService.GetOrCreateBasketForUser(GetOrSetBasketCookieAndUserName());
|
||||
var updateModel = items.ToDictionary(b => b.Id.ToString(), b => b.Quantity);
|
||||
await _basketService.SetQuantities(BasketModel.Id, updateModel);
|
||||
|
||||
await SetBasketModelAsync();
|
||||
var basket = await _basketService.SetQuantities(basketView.Id, updateModel);
|
||||
BasketModel = await _basketViewModelService.Map(basket);
|
||||
}
|
||||
|
||||
private async Task SetBasketModelAsync()
|
||||
private string GetOrSetBasketCookieAndUserName()
|
||||
{
|
||||
if (_signInManager.IsSignedIn(HttpContext.User))
|
||||
{
|
||||
BasketModel = await _basketViewModelService.GetOrCreateBasketForUser(User.Identity.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetOrSetBasketCookieAndUserName();
|
||||
BasketModel = await _basketViewModelService.GetOrCreateBasketForUser(_username);
|
||||
string userName = null;
|
||||
|
||||
if (Request.HttpContext.User.Identity.IsAuthenticated)
|
||||
{
|
||||
return Request.HttpContext.User.Identity.Name;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetOrSetBasketCookieAndUserName()
|
||||
{
|
||||
if (Request.Cookies.ContainsKey(Constants.BASKET_COOKIENAME))
|
||||
{
|
||||
_username = Request.Cookies[Constants.BASKET_COOKIENAME];
|
||||
userName = Request.Cookies[Constants.BASKET_COOKIENAME];
|
||||
|
||||
if (!Request.HttpContext.User.Identity.IsAuthenticated)
|
||||
{
|
||||
if (!Guid.TryParse(_username, out var _))
|
||||
if (!Guid.TryParse(userName, out var _))
|
||||
{
|
||||
_username = null;
|
||||
userName = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_username != null) return;
|
||||
if (userName != null) return userName;
|
||||
|
||||
_username = Guid.NewGuid().ToString();
|
||||
userName = Guid.NewGuid().ToString();
|
||||
var cookieOptions = new CookieOptions { IsEssential = true };
|
||||
cookieOptions.Expires = DateTime.Today.AddYears(10);
|
||||
Response.Cookies.Append(Constants.BASKET_COOKIENAME, _username, cookieOptions);
|
||||
Response.Cookies.Append(Constants.BASKET_COOKIENAME, userName, cookieOptions);
|
||||
|
||||
return userName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.eShopWeb.Infrastructure.Identity;
|
||||
using Microsoft.eShopWeb.Web.Interfaces;
|
||||
using Microsoft.eShopWeb.Web.Pages.Basket;
|
||||
using Microsoft.eShopWeb.Web.ViewModels;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopWeb.Web.Pages.Shared.Components.BasketComponent
|
||||
@@ -22,25 +20,27 @@ namespace Microsoft.eShopWeb.Web.Pages.Shared.Components.BasketComponent
|
||||
_signInManager = signInManager;
|
||||
}
|
||||
|
||||
public async Task<IViewComponentResult> InvokeAsync(string userName)
|
||||
public async Task<IViewComponentResult> InvokeAsync()
|
||||
{
|
||||
var vm = new BasketComponentViewModel();
|
||||
vm.ItemsCount = (await GetBasketViewModelAsync()).Items.Sum(i => i.Quantity);
|
||||
var vm = new BasketComponentViewModel
|
||||
{
|
||||
ItemsCount = await CountTotalBasketItems()
|
||||
};
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
private async Task<BasketViewModel> GetBasketViewModelAsync()
|
||||
private async Task<int> CountTotalBasketItems()
|
||||
{
|
||||
if (_signInManager.IsSignedIn(HttpContext.User))
|
||||
{
|
||||
return await _basketService.GetOrCreateBasketForUser(User.Identity.Name);
|
||||
return await _basketService.CountTotalBasketItems(User.Identity.Name);
|
||||
}
|
||||
|
||||
string anonymousId = GetAnnonymousIdFromCookie();
|
||||
if (anonymousId == null)
|
||||
return new BasketViewModel();
|
||||
return 0;
|
||||
|
||||
return await _basketService.GetOrCreateBasketForUser(anonymousId);
|
||||
return await _basketService.CountTotalBasketItems(anonymousId);
|
||||
}
|
||||
|
||||
private string GetAnnonymousIdFromCookie()
|
||||
|
||||
@@ -34,20 +34,9 @@ namespace Microsoft.eShopWeb.Web.Services
|
||||
{
|
||||
return await CreateBasketForUser(userName);
|
||||
}
|
||||
return await CreateViewModelFromBasket(basket);
|
||||
}
|
||||
|
||||
private async Task<BasketViewModel> CreateViewModelFromBasket(Basket basket)
|
||||
{
|
||||
var viewModel = new BasketViewModel
|
||||
{
|
||||
Id = basket.Id,
|
||||
BuyerId = basket.BuyerId,
|
||||
Items = await GetBasketItems(basket.Items)
|
||||
};
|
||||
|
||||
var viewModel = await Map(basket);
|
||||
return viewModel;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<BasketViewModel> CreateBasketForUser(string userId)
|
||||
{
|
||||
@@ -84,5 +73,24 @@ namespace Microsoft.eShopWeb.Web.Services
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public async Task<BasketViewModel> Map(Basket basket)
|
||||
{
|
||||
return new BasketViewModel()
|
||||
{
|
||||
BuyerId = basket.BuyerId,
|
||||
Id = basket.Id,
|
||||
Items = await GetBasketItems(basket.Items)
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<int> CountTotalBasketItems(string username)
|
||||
{
|
||||
var basketSpec = new BasketWithItemsSpecification(username);
|
||||
var basket = await _basketRepository.GetBySpecAsync(basketSpec);
|
||||
if (basket == null)
|
||||
return 0;
|
||||
return basket.Items.Sum(i => i.Quantity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
</section>
|
||||
|
||||
<section class="col-lg-1 col-xs-12">
|
||||
@await Component.InvokeAsync("Basket", User.Identity.Name)
|
||||
@await Component.InvokeAsync("Basket")
|
||||
</section>
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user