Desidero modificare un codice in un'azione dell'azione OpcSaveBilling da CheckoutController. Non voglio modificare il codice principale di NopCommerce, quindi ho bisogno di provare a sovrascrivere il codice con il mio codice personalizzato.Come implementare un filtro azione in NopCommerce
Ho letto questo articolo per iniziare http://www.pronopcommerce.com/overriding-intercepting-nopcommerce-controllers-and-actions. Da quello che ho letto, puoi eseguire il tuo codice prima che un'azione venga eseguita e dopo che un'azione è stata eseguita. Ma quello che non sto ottenendo è la parte che l'articolo sta lasciando aperto (il codice effettivo che deve essere eseguito).
Quello che voglio di base è la stessa funzione del codice originale ma con alcune modifiche personalizzate. Ho aggiunto una casella di controllo nella vista OnePageCheckout e in base a tale casella di controllo è necessario saltare la parte di invio degli indirizzi di spedizione nel checkout o meno. (Utilizzare l'indirizzo di fatturazione per l'indirizzo di spedizione)
Ho già aggiunto il codice nel codice principale e questo funziona e salta il passaggio (NOTA: so che devo ancora aggiungere manualmente l'indirizzo di fatturazione come indirizzo di spedizione) ma come ho detto non voglio alterare il codice nel nucleo di NopCommerce ma sovrascriverlo.
Se la mia domanda non è comprensibile e avete bisogno di più codice o spiegazione, sono lieto di fornire altro. Se il modo in cui sto facendo questo non è adatto per quello che voglio, sarei grato se me lo dica!
Il mio codice:
La classe Operazione filtro:
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
}
}
}
Registrato classe in DependencyRegistar nello stesso plugin Nop
builder.RegisterType<ShippingAddressOverideActionFilter>().As<System.Web.Mvc.IFilterProvider>();
Un esempio di lavoro con l'abitudine codice in esso. Ma questo è nell'azione principale.
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 });
}
}
Grazie per la risposta. Se avessi messo un reindirizzamento a un controller + un'azione personalizzata in là come nella risposta, c'è un modo per inviare il parametro FormCollection che l'OpcSaveBilling ottiene quando viene chiamato con quel reindirizzamento in modo da poter usare nella mia azione personalizzata? –