2014-09-08 3 views
5

Я хочу изменить некоторый код в действии действия OpcSaveBilling с CheckoutController. Я не хочу изменять основной код NopCommerce, поэтому мне нужно попытаться переопределить код с помощью собственного кода.Как реализовать фильтр действий в NopCommerce

Я прочитал эту статью, чтобы начать работу http://www.pronopcommerce.com/overriding-intercepting-nopcommerce-controllers-and-actions. Из того, что я прочитал, вы можете выполнить свой собственный код до того, как действие будет выполнено и после того, как действие будет выполнено. Но то, что я не получаю, является тем, что статья остается открытой (фактический код, который нужно выполнить).

То, что я в основном хочу, является той же функцией исходного кода, но с некоторыми пользовательскими настройками. Я добавил флажок в представлении OnePageCheckout и на основании этого флажка ему нужно пропустить часть входящих адресов доставки в кассе или нет. (Используйте адрес фактурирования для адреса доставки)

У меня уже есть код, добавленный в основной код и эта работа, и пропустит этот шаг (ПРИМЕЧАНИЕ. Я знаю, что мне все равно нужно вручную добавить платежный адрес в качестве адреса доставки) но, как я уже сказал, я не хочу изменять код в ядре NopCommerce, но переопределять его.

Если мой вопрос непонятен, и вам нужно больше кода или объяснений, я с удовольствием предоставил больше. Если способ, которым я это делаю, не подходит для того, что я хочу, я был бы признателен, если бы вы сказали мне!

Мой код:

Класс Действие фильтра:

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 
    } 
} 

}

Зарегистрированный класс в DependencyRegistar в том же Nop плагин

builder.RegisterType<ShippingAddressOverideActionFilter>().As<System.Web.Mvc.IFilterProvider>(); 

рабочий пример с обычаем код в нем. Но это в основном действии.

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 }); 
     } 
    } 

ответ

6

Никто не может сказать вам, что вам нужно положить в 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 
    } 

Правило большого пальца? Напишите любой код, как, как вы напишете действие. Единственная настройка - вместо того, чтобы возвращать ActionResult, вы должны установить filterContext.Result (вы ничего не можете вернуть, поскольку это метод void).

Например, при настройке следующего будет перенаправляться на домашнюю страницу, даже если вы выполняете действие, которое вы переопределяете.

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

Помните, что это OnActionExecuting, так что это выполняется перед действием, которое вы переопределяете. И если вы перенаправляете его на другую страницу, он не будет вызывать действие, которое вы переопределяете. :)

+1

Благодарим вас за ответ. Если бы я перенаправил на пользовательский контроллер + действие, как в вашем ответе, есть ли способ отправить параметр FormCollection, который получает OpcSaveBilling при вызове с этим перенаправлением, чтобы я мог использовать его в своем настраиваемом действии? –

Смежные вопросы