I'm not understanding why I'm getting an error while trying to add a product to a cart in my DB. I have a product that I want to add to cart. If a cart does not exist then we create a new cart and add it to the db. Every time we add the same product it should increase the count by 1. It should populate the cart with said product but I get an Exception has occurred: CLR/System.InvalidOperationException An exception of type 'System.InvalidOperationException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'Invalid operation. The connection is closed.'
error message. ASP.NET Core MVC 8
private readonly ILogger<ShoppingCartController> _logger;
private readonly DBContext _dbContext;
private const string CartSessionKey = "CartId";
private string ShoppingCartId { get; set;}
public ShoppingCartController(ILogger<ShoppingCartController> logger, DBContext dBContext)
{
_logger = logger;
_dbContext = dBContext;
}
public async void AddToCart(int id)
{
ShoppingCartId = GetCartID();
// Bottom line code breaks with the InvalidOperationException
Cart cart = await _dbContext.Carts.FirstOrDefaultAsync(c => c.CartId == ShoppingCartId && c.ProductId == id);
if (cart == null)
{
// If cart is null then we create a new cart
Cart newCart = new Cart
{
ProductId = id,
CartId = ShoppingCartId,
Product = await _dbContext.Products.FirstOrDefaultAsync(p => p.ProductId == id),
Count = 1,
CreatedDate = DateTime.Now,
};
await _dbContext.Carts.AddAsync(newCart);
}
else
{
cart.Count++;
}
await _dbContext.SaveChangesAsync();
}
private string GetCartID()
{
if(HttpContext.Session.Keys.Contains(CartSessionKey) == false)
{
if (!string.IsNullOrWhiteSpace(HttpContext.User.Identity.Name))
{
HttpContext.Session.SetString(CartSessionKey,HttpContext.User.Identity.Name);
}
else
{
Guid tempCartId = Guid.NewGuid();
HttpContext.Session.SetString(CartSessionKey, tempCartId.ToString());
}
}
return HttpContext.Session.GetString(CartSessionKey);
}
}
<div class="d-flex">
<div class="row rows-cols-4">
@foreach(var prod in @ViewBag.Products)
{
<div class="card m-1" style="width: 18rem;">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">@prod.ProductName</h5>
<a class="btn btn-primary" asp-controller="Customer" asp-action="ProductDetails" asp-route-id="@prod.ProductId">More Details</a>
// This is where it would add the product to cart
<a class="btn btn-primary" asp-controller="ShoppingCart" asp-action="AddToCart" asp-route-id="@prod.ProductId">Add to cart</a>
</div>
</div>
}
</div>
</div>
public class Cart
{
public int Id { get; set; }
public int Count { get; set; }
public string CartId { get; set; }
public DateTime CreatedDate { get; set; }
public int ProductId { get; set; }
public virtual Product Product { get; set; }
}
You have a few issues that should be addressed:
_dBContext.Carts.Add(newCart);
and not AddAsync()
. AddAsync
should only be used in very specific circumstances when you have special sql generators that require async access to your database.
Task
. So, your method signature should look like this:public async Task AddToCart(int id)
It seems that, because of your async void
, EF was closing your DBContext Connection early, which was throwing the exception above.