gpt4 book ai didi

c# - 如何在 NopCommerce 中实现 Action 过滤器

转载 作者:太空狗 更新时间:2023-10-30 01:03:55 24 4
gpt4 key购买 nike

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

我已阅读这篇文章以帮助我入门 http://www.pronopcommerce.com/overriding-intercepting-nopcommerce-controllers-and-actions .从我读过的内容来看,您可以在执行操作之前和执行操作之后执行自己的代码。但我没有得到的是文章未完成的部分(需要执行的实际代码)。

我基本上想要的是原始代码的相同功能,但有一些自定义调整。我在 OnePageCheckout View 中添加了一个复选框,并且基于该复选框,它需要跳过结帐中是否输入送货地址部分。 (使用账单地址作为送货地址)

我已经将该代码添加到核心代码中,并且可以正常工作并跳过该步骤(注意:我知道我仍然需要手动添加帐单地址作为送货地址)但是就像我说的我不想改变NopCommerce 核心中的代码,但覆盖了它。

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

我的代码:

Action 过滤器类:

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<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
if (controllerContext.Controller is CheckoutController && actionDescriptor.ActionName.Equals("OpcSaveBilling", StringComparison.InvariantCultureIgnoreCase))
{
return new List<Filter>() { new Filter(this, FilterScope.Action, 0) };
}
return new List<Filter>();
}

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<ShippingAddressOverideActionFilter>().As<System.Web.Mvc.IFilterProvider>();

其中包含自定义代码的工作示例。但这是核心 Action 。

  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<ShippingOption>(_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 一样编写任何代码。唯一的调整是,您应该设置 filterContext.Result 而不是返回 ActionResult(您不能返回任何内容,因为这是一个 void 方法)。

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

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

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

关于c# - 如何在 NopCommerce 中实现 Action 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25723821/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com