如何在NopCommerce中实现动作filter

我想从CheckoutController更改OpcSaveBilling操作的一些代码中的一些代码。 我不想改变NopCommerce的核心代码,所以我需要尝试使用我自己的自定义代码覆盖代码。

我读过这篇文章是为了让我开始http://www.pronopcommerce.com/overriding-intercepting-nopcommerce-controllers-and-actions 。 根据我的阅读,您可以在执行操作之前和执行操作之后执行自己的代码。 但我没有得到的是文章留下的部分(需要执行的实际代码)。

我基本上想要的是原始代码的相同function,但有一些自定义调整。 我在OnePageCheckout视图中添加了一个复选框,根据该复选框,它需要在结帐时跳过输入送货地址部分。 (使用送货地址的帐单邮寄地址)

我已经在核心代码和这项工作中添加了代码并跳过了这一步(注意:我知道我仍然需要手动添加帐单地址作为送货地址)但是就像我说我不想改变代码NopCommerce的核心,但覆盖它。

如果我的问题不可理解,您需要更多代码或解释,我很乐意提供更多。 如果我这样做的方式不适合我想要的,如果你告诉我,我将不胜感激!

我的代码:

Action Filter类:

using Nop.Web.Controllers; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web.Mvc; namespace Nop.Plugin.Misc.MyProject.ActionFilters { class ShippingAddressOverideActionFilter : ActionFilterAttribute, IFilterProvider { public IEnumerable GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { if (controllerContext.Controller is CheckoutController && actionDescriptor.ActionName.Equals("OpcSaveBilling", StringComparison.InvariantCultureIgnoreCase)) { return new List() { new Filter(this, FilterScope.Action, 0) }; } return new List(); } public override void OnActionExecuting(ActionExecutingContext filterContext) { // What do I put in here? So that I have the code of the core action but with my custom tweaks in it } } 

}

在同一个Nop插件中将DependencyRegistar中的类注册

  builder.RegisterType().As(); 

一个包含自定义代码的工作示例。 但这是核心行动。

  public ActionResult OpcSaveBilling(FormCollection form) { try { //validation var cart = _workContext.CurrentCustomer.ShoppingCartItems .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart) .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id) .ToList(); if (cart.Count == 0) throw new Exception("Your cart is empty"); if (!UseOnePageCheckout()) throw new Exception("One page checkout is disabled"); if ((_workContext.CurrentCustomer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed)) throw new Exception("Anonymous checkout is not allowed"); int billingAddressId = 0; int.TryParse(form["billing_address_id"], out billingAddressId); if (billingAddressId > 0) { //existing address var address = _workContext.CurrentCustomer.Addresses.FirstOrDefault(a => a.Id == billingAddressId); if (address == null) throw new Exception("Address can't be loaded"); _workContext.CurrentCustomer.BillingAddress = address; _customerService.UpdateCustomer(_workContext.CurrentCustomer); } else { //new address var model = new CheckoutBillingAddressModel(); TryUpdateModel(model.NewAddress, "BillingNewAddress"); //validate model TryValidateModel(model.NewAddress); if (!ModelState.IsValid) { //model is not valid. redisplay the form with errors var billingAddressModel = PrepareBillingAddressModel(selectedCountryId: model.NewAddress.CountryId); billingAddressModel.NewAddressPreselected = true; return Json(new { update_section = new UpdateSectionJsonModel() { name = "billing", html = this.RenderPartialViewToString("OpcBillingAddress", billingAddressModel) }, wrong_billing_address = true, }); } //try to find an address with the same values (don't duplicate records) var address = _workContext.CurrentCustomer.Addresses.ToList().FindAddress( model.NewAddress.FirstName, model.NewAddress.LastName, model.NewAddress.PhoneNumber, model.NewAddress.Email, model.NewAddress.FaxNumber, model.NewAddress.Company, model.NewAddress.Address1, model.NewAddress.Address2, model.NewAddress.City, model.NewAddress.StateProvinceId, model.NewAddress.ZipPostalCode, model.NewAddress.CountryId); if (address == null) { //address is not found. let's create a new one address = model.NewAddress.ToEntity(); address.CreatedOnUtc = DateTime.UtcNow; //some validation if (address.CountryId == 0) address.CountryId = null; if (address.StateProvinceId == 0) address.StateProvinceId = null; if (address.CountryId.HasValue && address.CountryId.Value > 0) { address.Country = _countryService.GetCountryById(address.CountryId.Value); } _workContext.CurrentCustomer.Addresses.Add(address); } _workContext.CurrentCustomer.BillingAddress = address; _customerService.UpdateCustomer(_workContext.CurrentCustomer); } // Get value of checkbox from the one page checkout view var useSameAddress = false; Boolean.TryParse(form["billing-address-same"], out useSameAddress); // If it is checked copy the billing address to shipping address and skip the shipping address part of the checkout if (useSameAddress) { var shippingMethodModel = PrepareShippingMethodModel(cart); return Json(new { update_section = new UpdateSectionJsonModel() { name = "shipping-method", html = this.RenderPartialViewToString("OpcShippingMethods", shippingMethodModel) }, goto_section = "shipping_method" }); } // If it isn't checked go to the enter shipping address part of the checkout else { if (cart.RequiresShipping()) { //shipping is required var shippingAddressModel = PrepareShippingAddressModel(prePopulateNewAddressWithCustomerFields: true); return Json(new { update_section = new UpdateSectionJsonModel() { name = "shipping", html = this.RenderPartialViewToString("OpcShippingAddress", shippingAddressModel) }, goto_section = "shipping" }); } else { //shipping is not required _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.SelectedShippingOption, null, _storeContext.CurrentStore.Id); //load next step return OpcLoadStepAfterShippingMethod(cart); } } } catch (Exception exc) { _logger.Warning(exc.Message, exc, _workContext.CurrentCustomer); return Json(new { error = 1, message = exc.Message }); } } 

没有人可以告诉你你需要在OnActionExecuting中放什么,因为你可以做很多事情。

 public override void OnActionExecuting(ActionExecutingContext filterContext) { // What do I put in here? So that I have the code of the core action but with my custom tweaks in it } 

经验法则? 编写任何代码,比如你将如何写一个Action。 唯一的调整是,而不是返回ActionResult,你应该设置filterContext.Result (你不能返回任何东西,因为这是一个void方法)。

例如,在执行您要覆盖的操作之前,设置以下内容将重定向到主页。

 filterContext.Result = new RedirectToRouteResult("HomePage", null); 

请记住这是OnActionExecuting,因此这将在您覆盖的Action之前执行。 如果您将其重定向到另一个页面,它将不会调用您重写的Action。 🙂