I'm making a shopping cart using ASP.NET Core Web API and react. When testing what was done in Swagger UI and Postman, everything works correctly, but when switching to react, problems begin. Each time when I add product in swagger/postman, all products are added with their ShoppingCartId
that is related to the current session. But when I tested it with React, after each added product a new ShoppingCartId
is created, which shouldn't happen. Below is the code and result:
Session Configuration:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped(sc => ShoppingCart.GetShoppingCart(sc));
services.AddDistributedMemoryCache();
services.AddSession(options => {
options.IdleTimeout = TimeSpan.FromMinutes(3600);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
ShoppingCart class:
public class ShoppingCart
{
public AppDbContext _context { get; set; }
public string ShoppingCartId { get; set; }
public List<ShoppingCartItem> ShoppingCartItem { get; set; }
public ShoppingCart(AppDbContext context)
{
_context = context;
}
public static ShoppingCart GetShoppingCart (IServiceProvider services)
{
ISession session = services.GetRequiredService<IHttpContextAccessor>()?.HttpContext.Session;
var context = services.GetService<AppDbContext>();
string cardId = session.GetString("CardId") ?? Guid.NewGuid().ToString();
session.SetString("CardId", cardId);
return new ShoppingCart(context) { ShoppingCartId = cardId };
}
public List<ShoppingCartItem> GetShoppingCartItems()
{
return ShoppingCartItem ?? (ShoppingCartItem = _context.ShoppingCartItem.Where(n => n.ShoppingCartId ==
ShoppingCartId).Include(n => n.Book).ToList());
}
public void AddItemToCart(Book book)
{
var shoppingCartItem = _context.ShoppingCartItem.FirstOrDefault(n => n.Book.Id == book.Id &&
n.ShoppingCartId == ShoppingCartId);
if(shoppingCartItem == null)
{
shoppingCartItem = new ShoppingCartItem()
{
ShoppingCartId = ShoppingCartId,
Book = book,
Amount = 1
};
_context.ShoppingCartItem.Add(shoppingCartItem);
}
else
{
shoppingCartItem.Amount++;
}
_context.SaveChanges();
}
}
Controller:
[Route("api/[controller]")]
[ApiController]
public class OrderController : ControllerBase
{
private readonly ShoppingCart _shoppingCart;
private readonly IOrderService _orderService;
public OrderController(ShoppingCart shoppingCart, IOrderService orderService)
{
_shoppingCart = shoppingCart;
_orderService = orderService;
}
[HttpGet("get-shopping-cart")]
public IActionResult GetShoppingCart()
{
var items = _shoppingCart.GetShoppingCartItems();
_shoppingCart.ShoppingCartItem = items;
var responce = new ShopCartVM()
{
ShoppingCartItem = items,
ShopCartTotal = _shoppingCart.GetShoppingCartTotal(),
TotalItems = _shoppingCart.GetShoppingCartItemsSummary()
};
return Ok(responce);
}
[HttpPost("add-item-to-cart")]
public async Task<IActionResult> AddItemToShoppingCart(int id)
{
var item = await _bookService.GetByIdShopAsync(id);
if (item != null)
{
_shoppingCart.AddItemToCart(item);
}
return RedirectToAction(nameof(GetShoppingCart));
}
}
React
export const addProduct = (productId: number) => async (dispatch: AppDispatch) => {
try {
const request = new XMLHttpRequest();
request.open("POST", `https://localhost:44307/api/Order/add-item-to-cart?id=${productId}`)
request.responseType = "text"
request.onload = function () {
const response = request.response;
console.log(response)
};
request.send();
} catch (e) {
console.log(e)
}
}
Update: I think the problem is that in React a new session is generated after each action, which does not happen in Swagger. What could be the reason for this and how to fix it?
Below is the screenshots with changes and static session: