NopCommerce 4.5自定义控制器下单函数调用及购物车清空咨询
我正在NopCommerce 4.5中创建带有下单功能的自定义控制器,已编写如下PlaceOrder异步方法代码,请问该如何调用此方法完成下单操作并清空购物车?
private async Task<Order> PlaceOrder(IList<ShoppingCartItem> cart) { var _orderProcessingService = EngineContext.Current.Resolve<IOrderProcessingService>(); var _genericAttributeService = EngineContext.Current.Resolve<IGenericAttributeService>(); var processPaymentRequest = HttpContext.Session.Get<ProcessPaymentRequest>("OrderPaymentInfo") ?? new ProcessPaymentRequest(); _paymentService.GenerateOrderGuid(processPaymentRequest); processPaymentRequest.StoreId = (await _storeContext.GetCurrentStoreAsync()).Id; processPaymentRequest.CustomerId = (await _workContext.GetCurrentCustomerAsync()).Id; processPaymentRequest.PaymentMethodSystemName = await _genericAttributeService.GetAttributeAsync<string>(await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.SelectedPaymentMethodAttribute, (await _storeContext.GetCurrentStoreAsync()).Id); HttpContext.Session.Set<ProcessPaymentRequest>("OrderPaymentInfo", processPaymentRequest); var placeOrderResult = await _orderProcessingService.PlaceOrderAsync(processPaymentRequest); if (placeOrderResult.Success) { HttpContext.Session.Set<ProcessPaymentRequest>("OrderPaymentInfo", null); var postProcessPaymentRequest = new PostProcessPaymentRequest { Order = placeOrderResult.PlacedOrder }; await _paymentService.PostProcessPaymentAsync(postProcessPaymentRequest); return postProcessPaymentRequest.Order; } else { return null; } }
调用方法及清空购物车的实现方案
嘿,我来帮你梳理下怎么调用这个PlaceOrder方法,顺便搞定购物车清空的流程:
1. 先注入必要的服务
首先,你的自定义控制器需要注入几个核心服务来获取购物车数据、当前用户和店铺信息。建议把PlaceOrder里用到的服务也通过构造注入(比直接用EngineContext.Resolve更符合NopCommerce规范):
private readonly IShoppingCartService _shoppingCartService; private readonly IWorkContext _workContext; private readonly IStoreContext _storeContext; private readonly IPaymentService _paymentService; private readonly IOrderProcessingService _orderProcessingService; private readonly IGenericAttributeService _genericAttributeService; // 构造函数注入所有依赖 public YourCustomController( IShoppingCartService shoppingCartService, IWorkContext workContext, IStoreContext storeContext, IPaymentService paymentService, IOrderProcessingService orderProcessingService, IGenericAttributeService genericAttributeService) { _shoppingCartService = shoppingCartService; _workContext = workContext; _storeContext = storeContext; _paymentService = paymentService; _orderProcessingService = orderProcessingService; _genericAttributeService = genericAttributeService; }
2. 创建调用PlaceOrder的Action
在控制器里新增一个异步Action(比如SubmitOrder)来处理下单请求:
public async Task<IActionResult> SubmitOrder() { // 1. 获取当前用户和店铺 var currentCustomer = await _workContext.GetCurrentCustomerAsync(); var currentStore = await _storeContext.GetCurrentStoreAsync(); // 2. 获取当前用户的购物车项 var cartItems = await _shoppingCartService.GetShoppingCartAsync( currentCustomer, ShoppingCartType.ShoppingCart, currentStore.Id); // 3. 检查购物车是否为空 if (!cartItems.Any()) { TempData["ErrorMessage"] = "购物车为空,无法下单"; return RedirectToAction("Index", "ShoppingCart"); } // 4. 调用你的PlaceOrder方法 var placedOrder = await PlaceOrder(cartItems); // 5. 处理下单结果 if (placedOrder != null) { // 下单成功,清空购物车 await _shoppingCartService.DeleteShoppingCartAsync( currentCustomer, ShoppingCartType.ShoppingCart, currentStore.Id); // 跳转到订单详情页或返回成功提示 return RedirectToAction("Details", "Order", new { orderId = placedOrder.Id }); } else { // 下单失败,返回错误提示(可以优化PlaceOrder返回具体错误信息) TempData["ErrorMessage"] = "下单失败,请检查支付配置后重试"; return RedirectToAction("Checkout", "ShoppingCart"); } }
3. 优化PlaceOrder方法(可选但推荐)
把PlaceOrder里的EngineContext.Resolve替换成构造注入的服务,同时可以改成返回PlaceOrderResult来获取更详细的失败信息:
private async Task<PlaceOrderResult> PlaceOrder(IList<ShoppingCartItem> cart) { var processPaymentRequest = HttpContext.Session.Get<ProcessPaymentRequest>("OrderPaymentInfo") ?? new ProcessPaymentRequest(); _paymentService.GenerateOrderGuid(processPaymentRequest); processPaymentRequest.StoreId = (await _storeContext.GetCurrentStoreAsync()).Id; processPaymentRequest.CustomerId = (await _workContext.GetCurrentCustomerAsync()).Id; processPaymentRequest.PaymentMethodSystemName = await _genericAttributeService.GetAttributeAsync<string>(await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.SelectedPaymentMethodAttribute, (await _storeContext.GetCurrentStoreAsync()).Id); HttpContext.Session.Set<ProcessPaymentRequest>("OrderPaymentInfo", processPaymentRequest); var placeOrderResult = await _orderProcessingService.PlaceOrderAsync(processPaymentRequest); if (placeOrderResult.Success) { HttpContext.Session.Set<ProcessPaymentRequest>("OrderPaymentInfo", null); var postProcessPaymentRequest = new PostProcessPaymentRequest { Order = placeOrderResult.PlacedOrder }; await _paymentService.PostProcessPaymentAsync(postProcessPaymentRequest); } return placeOrderResult; }
修改后,你可以在调用时通过placeOrderResult.Errors拿到具体失败原因,给用户更精准的提示。
内容的提问来源于stack exchange,提问作者Dev.s
相关产品推荐
相关产品推荐

