ASP.NET MVC购物车开发问题:路由匹配冲突报错及同系列书籍折扣功能实现需求
Let's tackle your problems one by one—first the routing error, then the series-based discount feature.
1. Fixing the AmbiguousActionException
Looking at your ProductController code, there's a syntax error in your route attribute that's contributing to the issue:
[Route("~/"))] // Extra closing parenthesis here!
Change that line to:
[Route("~/")]
Even after fixing that syntax, if your project includes a default HomeController with an Index method (standard in ASP.NET MVC templates), accessing the root URL (/) will match both HomeController.Index and ProductController.Index—this is exactly what's triggering the AmbiguousActionException.
Resolve this with one of these straightforward options:
- Option 1: Set Product as the default controller
In yourProgram.cs(orStartup.csfor older .NET versions), update the default route configuration to point toProductinstead ofHome:app.MapControllerRoute( name: "default", pattern: "{controller=Product}/{action=Index}/{id?}"); - Option 2: Remove the root route from ProductController
Delete the[Route("~/")]attribute fromProductController.Index. This will make the product index only accessible via/productor/product/index, leavingHomeController.Indexas the root page.
Also, double-check you've configured session correctly (required for your cart functionality) in Program.cs:
// Add session services builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(30); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; }); // ... // Enable session after routing, before endpoints app.UseSession();
2. Implementing Series-Based Discounts
First, ensure your Product model includes a Series property (e.g., "漫威", "DC") to group books by their respective series.
Next, modify the total price calculation in CartController.Index to apply discounts per series:
public IActionResult Index() { var cart = SessionHelper.GetObjectFromJson<List<Item>>(HttpContext.Session, "cart"); ViewBag.cart = cart; if (cart == null || cart.Count == 0) { ViewBag.total = 0; return View(); } // Group cart items by product series var seriesGroups = cart.GroupBy(item => item.Product.Series); decimal total = 0; foreach (var group in seriesGroups) { int totalQuantityInSeries = group.Sum(item => item.Quantity); decimal seriesSubtotal = group.Sum(item => item.Product.Price * item.Quantity); // Apply 10% discount for Marvel series with 2+ books if (group.Key.Equals("漫威", StringComparison.OrdinalIgnoreCase) && totalQuantityInSeries >= 2) { seriesSubtotal *= 0.9m; // 10% off = 90% of original // Optional: Add discount info to display to users ViewBag.Discounts ??= new List<string>(); ViewBag.Discounts.Add($"漫威系列 ({totalQuantityInSeries}本): 享受10%折扣"); } total += seriesSubtotal; } ViewBag.total = total; return View(); }
You can enhance your cart view by adding a section to loop through ViewBag.Discounts (if it exists) to make the discount details visible to users.
Bonus: Clean Up Redundant Route Attributes
For better maintainability, simplify your controller routes:
- On
ProductController, the[Route("product")]attribute prefixes all actions with/product. The empty[Route("")]onIndexalready maps/productto the index action, so you can remove the redundant[Route("index")]if you don't need/product/indexto work (or keep it if you want both URLs to function).
内容的提问来源于stack exchange,提问作者SCB3603

