using Core.Entites;
using Core.Interfaces;
using StackExchange.Redis;
using System.Text.Json;
namespace Infrastructure.Services
{
public class CartService(IConnectionMultiplexer redis) : ICartService
{
private readonly IDatabase _database = redis.GetDatabase();
public async Task<bool> DeleteCartAsync(string key)
{
return await _database.KeyDeleteAsync(key);
}
public async Task<ShoppingCart?> GetCartAsync(string key)
{
var data = await _database.StringGetAsync(key);
return data.IsNullOrEmpty ? null : JsonSerializer.Deserialize<ShoppingCart>(data!);
}
public async Task<ShoppingCart?> SetCartAsync(ShoppingCart cart)
{
var created = await _database.StringSetAsync(cart.Id, JsonSerializer.Serialize(cart),
TimeSpan.FromDays(30));
if (!created) return null;
return await GetCartAsync(cart.Id);
}
}
}
using Core.Entites;
using Core.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Text.Json;
namespace API.Controllers
{
public class CartController : BaseAPIController
{
private readonly ICartService _cartService;
private readonly JsonSerializerOptions _jsonOptions;
private readonly ILogger<CartController> _logger;
public CartController(ICartService cartService, ILogger<CartController> logger)
{
_cartService = cartService;
_logger = logger; // Fixed: Correctly assign logger to _logger
_jsonOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
}
[HttpGet]
public async Task<ActionResult<ShoppingCart>> GetCartById(string id)
{
var cart = await _cartService.GetCartAsync(id);
return Ok(cart ?? new ShoppingCart { Id = id, Items = new List<CartItem>() });
}
[HttpPost]
public async Task<ActionResult<ShoppingCart>> UpdateCart([FromBody] JsonElement cartData)
{
try
{
// Log the raw JSON
_logger.LogInformation("Received cart data: {CartData}", cartData.GetRawText());
ShoppingCart? cart = null;
if (cartData.TryGetProperty("ms", out var msProperty))
{
// Handle the case where the cart data is nested under 'ms'
_logger.LogInformation("Cart data nested under 'ms' property");
var items = JsonSerializer.Deserialize<List<CartItem>>(msProperty.GetRawText(), _jsonOptions);
cart = new ShoppingCart { Id = Guid.NewGuid().ToString(), Items = items ?? new List<CartItem>() };
}
else
{
// Try to deserialize directly to ShoppingCart
_logger.LogInformation("Attempting to deserialize directly to ShoppingCart");
cart = JsonSerializer.Deserialize<ShoppingCart>(cartData.GetRawText(), _jsonOptions);
}
if (cart == null)
{
_logger.LogWarning("Failed to deserialize cart data");
return BadRequest("Invalid cart data");
}
// Log the deserialized cart
_logger.LogInformation("Deserialized cart: {@Cart}", cart);
// Ensure Id is set
if (string.IsNullOrEmpty(cart.Id))
{
cart.Id = Guid.NewGuid().ToString();
}
var updatedCart = await _cartService.SetCartAsync(cart);
if (updatedCart == null) return BadRequest("Problem updating the cart");
return Ok(updatedCart);
}
catch (JsonException ex)
{
_logger.LogError(ex, "Error parsing cart data");
return BadRequest($"Error parsing cart data: {ex.Message}");
}
}
[HttpDelete]
public async Task<ActionResult> DeleteCart(string id)
{
var result = await _cartService.DeleteCartAsync(id);
if (!result) return BadRequest("Problem deleting the cart");
return Ok();
}
}
}
Angular cart item.ts:
export type ICartItem = {
productId: number;
productName: string;
price: number;
quantity: number;
pictureUrl: string;
brand: string;
type: string;
}
export class Cart implements ICart {
id = nanoid();
items: ICartItem[] = [];
}
I have done all possible troubleshooting which includes re-writing all the relevant code. any assistance would be helpful
- Refresh the servers: client and API
- reviewed the code for error 3 Re-written the code for the cart service
- added models for additional log errors for more information from the Redis server that I’m using
When Api test in postman for the: Get, Post and Delete functions all came back 200ok
Server error message:
Error parsing cart data: JSON deserialization for type ‘Cart-Item’ was missing required properties, >including the following: brand, type
Payload:{id: “h6O583EhuewJz7dgpyRFc”,…}
id
:
“h6O583EhuewJz7dgpyRFc”
items
:
[{productId: 3, productName: “Core Board Speed Rush 3”, price: 180, quantity: 1,…}]
0
:
{productId: 3, productName: “Core Board Speed Rush 3”, price: 180, quantity: 1,…}
I notice that that nanoid is generating a shopping cart id however the cart is not being stored to the Redis server