У меня проблема с файлом ShoppingCartService.cs! Когда программы переходят к методу public async Task AddToCart(int bookId), он успешно добавляет товар в корзину, но когда он переходит к последней строке -> SaveShoppingCart(shoppingCart); я потеряю все?? Почему это? Извините за невежество, я был бы признателен, если бы кто-нибудь из вас объяснил, в чем моя ошибка, спасибо!
Код: Выделить всё
` public async Task AddToCart(int bookId)
{
var shoppingCart = GetShoppingCart();
var book = await _bookService.GetBookByIdAsync(bookId);
if (book == null) return;
var cartItem = shoppingCart.Items.FirstOrDefault(i => i.BookId == bookId);
if (cartItem == null)
{
shoppingCart.Items.Add(new CartItem { BookId = bookId, Book = book, Quantity = 1 });
}
else
{
cartItem.Quantity++;
}
SaveShoppingCart(shoppingCart);
}`
Я добавил builder.Services.AddSession(options =>
Код: Выделить всё
{ options.IdleTimeout = TimeSpan.FromMinutes(30); // Adjust as needed options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; });
Код: Выделить всё
`app.UseRouting();
app.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
`
Код: Выделить всё
`builder.Services.AddHttpContextAccessor();`
ShoppingCartController.cs ->
Код: Выделить всё
using Microsoft.AspNetCore.Mvc;
public class ShoppingCartController : Controller
{
private readonly IShoppingCartService _shoppingCartService;
public ShoppingCartController(IShoppingCartService
shoppingCartService)
{
_shoppingCartService = shoppingCartService;
}
public IActionResult CheckSession()
{
var testValue = HttpContext.Session.GetString("Test");
if (string.IsNullOrEmpty(testValue))
{
HttpContext.Session.SetString("Test", "Session is
working!");
}
return Content(HttpContext.Session.GetString("Test"));
}
public IActionResult Index()
{
var items = _shoppingCartService.GetCartItems();
var total = _shoppingCartService.GetCartTotal();
ViewBag.Items = items;
ViewBag.TotalPrice = total;
return View();
}
public IActionResult AddToCart(int bookId)
{
_shoppingCartService.AddToCart(bookId);
return RedirectToAction("Index");
}
public IActionResult RemoveFromCart(int bookId)
{
_shoppingCartService.RemoveFromCart(bookId);
return RedirectToAction("Index");
}
public IActionResult ClearCart()
{
_shoppingCartService.ClearCart();
return RedirectToAction("Index");
}
}
Код: Выделить всё
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
namespace SessionExtensions.Helpers
{
public static class SessionExtensions
{
public static void SetObjectAsJson(this ISession session, string key, object value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T GetObjectFromJson(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default(T) : JsonConvert.DeserializeObject(value);
}
}
}
Код: Выделить всё
public class ShoppingCart
{
public List Items { get; set; } = new List();
public decimal GetTotalPrice()
{
return Items.Sum(item => item.Book.Price * item.Quantity);
}
}
Код: Выделить всё
public interface IShoppingCartService
{
Task AddToCart(int bookId);
void RemoveFromCart(int bookId);
void ClearCart();
List GetCartItems();
decimal GetCartTotal();
}
Код: Выделить всё
using Bookshop_ASP.NET_Core_MVC_Application.Services;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using SessionExtensions.Helpers;
using System.Linq;
using System.Threading.Tasks;
public class ShoppingCartService : IShoppingCartService
{
private readonly IBookService _bookService;
private readonly IHttpContextAccessor _httpContextAccessor;
private const string CartSessionKey = "ShoppingCart";
public ShoppingCartService(IBookService bookService, IHttpContextAccessor httpContextAccessor)
{
_bookService = bookService;
_httpContextAccessor = httpContextAccessor;
}
public async Task AddToCart(int bookId)
{
var shoppingCart = GetShoppingCart();
var book = await _bookService.GetBookByIdAsync(bookId);
if (book == null) return;
var cartItem = shoppingCart.Items.FirstOrDefault(i => i.BookId == bookId);
if (cartItem == null)
{
shoppingCart.Items.Add(new CartItem { BookId = bookId, Book = book, Quantity = 1 });
}
else
{
cartItem.Quantity++;
}
SaveShoppingCart(shoppingCart);
}
public void RemoveFromCart(int bookId)
{
var shoppingCart = GetShoppingCart();
var cartItem = shoppingCart.Items.FirstOrDefault(i => i.BookId == bookId);
if (cartItem != null)
{
shoppingCart.Items.Remove(cartItem);
}
SaveShoppingCart(shoppingCart);
}
public void ClearCart()
{
var session = _httpContextAccessor.HttpContext?.Session;
if (session == null)
{
throw new InvalidOperationException("Session is not available.");
}
session.Remove(CartSessionKey);
}
public List GetCartItems()
{
return GetShoppingCart().Items;
}
public decimal GetCartTotal()
{
var shoppingCart = GetShoppingCart();
return shoppingCart.Items.Sum(i => i.Book.Price * i.Quantity);
}
private ShoppingCart GetShoppingCart()
{
var session = _httpContextAccessor.HttpContext?.Session;
if (session == null)
{
throw new InvalidOperationException("Session is not available.");
}
var cart = session.GetObjectFromJson(CartSessionKey) ?? new ShoppingCart();
//Check if the session is retrieving the cart
Console.WriteLine("Cart retrieved from session: " + JsonConvert.SerializeObject(cart));
return cart;
}
private void SaveShoppingCart(ShoppingCart shoppingCart)
{
var session = _httpContextAccessor.HttpContext?.Session;
if (session == null)
{
throw new InvalidOperationException("Session is not available.");
}
// Serialize and store the cart
session.SetObjectAsJson(CartSessionKey, shoppingCart);
// DEBUG: Retrieve the cart immediately after saving to confirm it was saved
var sessionCart = session.GetObjectFromJson(CartSessionKey);
// Log the cart to the console
Console.WriteLine("Cart in session after Save: " + JsonConvert.SerializeObject(sessionCart));
if (sessionCart == null || sessionCart.Items.Count == 0)
{
Console.WriteLine("Error: Shopping cart was not saved properly.");
}
}
}
Код: Выделить всё
@{
ViewData["Title"] = "Shopping Cart";
}
Your Shopping Cart
Title
Quantity
Price
@foreach (var item in ViewBag.Items)
{
@item.Book.Title
@item.Quantity
@(item.Book.Price * item.Quantity)
[[email protected](]Remove[/url]
}
[b]Total: [/b]@ViewBag.TotalPrice
[[email protected](]Clear Cart[/url]
[url=#]Checkout[/url]
Код: Выделить всё
using System.Collections.Generic;
using System.Threading.Tasks;
using Bookshop_ASP.NET_Core_MVC_Application.Data;
using Bookshop_ASP.NET_Core_MVC_Application.Models;
using Microsoft.EntityFrameworkCore;
namespace Bookshop_ASP.NET_Core_MVC_Application.Services
{
public class BookService : IBookService
{
private readonly BookshopDbContext _context;
public BookService(BookshopDbContext context)
{
_context = context;
}
public async Task GetAllBooksAsync()
{
return await _context.Books
.Include(b => b.Author)
.Include(b => b.BookGenres)
.ThenInclude(bg => bg.Genre)
.ToListAsync();
}
public async Task GetBookByIdAsync(int id)
{
try
{
var book = await _context.Books
.Include(b => b.Author)
.Include(b => b.BookGenres)
.ThenInclude(bg => bg.Genre)
.FirstOrDefaultAsync(b => b.Id == id);
if (book == null)
{
Console.WriteLine($"No book found with ID: {id}");
}
return book;
}
catch (Exception ex)
{
// Log or throw the error to see if anything goes wrong during the query
Console.WriteLine($"Error fetching book: {ex.Message}");
return null;
}
}
public async Task CreateBookAsync(Book book)
{
_context.Add(book);
await _context.SaveChangesAsync();
}
public async Task UpdateBookAsync(Book book)
{
_context.Update(book);
await _context.SaveChangesAsync();
}
public async Task DeleteBookAsync(int id)
{
var book = await _context.Books.FindAsync(id);
if (book != null)
{
_context.Books.Remove(book);
await _context.SaveChangesAsync();
}
}
public async Task GetAuthorsAsync()
{
return await _context.Authors.ToListAsync();
}
public async Task GetGenresAsync()
{
return await _context.Genres.ToListAsync();
}
}
}
Код: Выделить всё
using Bookshop_ASP.NET_Core_MVC_Application.Models;
using Bookshop_ASP.NET_Core_MVC_Application.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace Bookshop_ASP.NET_Core_MVC_Application.Controllers
{
public class BooksController : Controller
{
private readonly IBookService _bookService;
public BooksController(IBookService bookService)
{
_bookService = bookService;
}
// GET: BooksController
public async Task Index()
{
var books = await _bookService.GetAllBooksAsync();
return View(books);
}
// GET: BooksController/Details/5
public async Task Details(int id)
{
var book = await _bookService.GetBookByIdAsync(id);
if (book == null)
{
return NotFound();
}
return View(book);
}
[HttpGet]
public async Task Create()
{
ViewBag.Authors = await _bookService.GetAuthorsAsync();
ViewBag.Genres = await _bookService.GetGenresAsync();
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task Create(Book book, int[] GenreIds)
{
Console.WriteLine("AuthorId: " + book.AuthorId);
Console.WriteLine("BookGenres: " + book.BookGenres);
// Manually find the author based on AuthorId and assign it
var author = (await _bookService.GetAuthorsAsync())
.FirstOrDefault(a => a.Id == book.AuthorId);
book.Author = author;
// Map selected genres to BookGenres collection
var selectedGenres = await _bookService.GetGenresAsync();
foreach (var genreId in GenreIds)
{
var genre = selectedGenres.FirstOrDefault(g => g.Id == genreId);
if (genre != null)
{
book.BookGenres.Add(new BookGenre { Book = book, Genre = genre });
}
}
if (!ModelState.IsValid)
{
foreach (var error in ModelState.Values.SelectMany(v => v.Errors))
{
Console.WriteLine(error.ErrorMessage);
}
}
if (ModelState.IsValid)
{
if (author != null)
{
await _bookService.CreateBookAsync(book);
return RedirectToAction(nameof(Index));
}
else
{
ModelState.AddModelError("AuthorId", "Invalid author selected.");
}
}
ViewBag.Authors = await _bookService.GetAuthorsAsync();
ViewBag.Genres = await _bookService.GetGenresAsync();
return View(book);
}
// GET: BooksController/Edit/5
public async Task Edit(int id)
{
var book = await _bookService.GetBookByIdAsync(id);
if (book == null) return NotFound();
ViewBag.Authors = await _bookService.GetAuthorsAsync();
ViewBag.Genres = await _bookService.GetGenresAsync();
return View(book);
}
// POST: BooksController/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task Edit(int id, [Bind("Id, Title, Price, PublicationDate, Description, AuthorId, GenreId, ImageUrl")] Book book)
{
if (id != book.Id) return NotFound();
if (ModelState.IsValid)
{
await _bookService.UpdateBookAsync(book);
return RedirectToAction(nameof(Index));
}
ViewBag.Authors = await _bookService.GetAuthorsAsync();
ViewBag.Genres = await _bookService.GetGenresAsync();
return View(book);
}
// GET: BooksController/Delete/5
public async Task Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var book = await _bookService.GetBookByIdAsync(id.Value);
if (book == null)
{
return NotFound();
}
return View(book);
}
// POST: BooksController/Delete/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task DeleteConfirmed(int id)
{
await _bookService.DeleteBookAsync(id);
return RedirectToAction(nameof(Index));
}
}
}
Код: Выделить всё
using Bookshop_ASP.NET_Core_MVC_Application.Data;
using Microsoft.EntityFrameworkCore;
using Bookshop_ASP.NET_Core_MVC_Application.Services;
using Bookshop.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContext(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))
.EnableSensitiveDataLogging()
.LogTo(Console.WriteLine, Microsoft.Extensions.Logging.LogLevel.Information));
builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddHttpContextAccessor();
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30); // Adjust this as necessary
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseRouting();
app.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
BookshopDbContextSeeder.Seed(app);
app.Run();
Я знаю, что использовал ChatGPT для генерации большей части кода и только что собрал его! Не распинай меня!
Подробнее здесь: https://stackoverflow.com/questions/790 ... my-project