2014-09-08 23 views
5

Tôi muốn thay đổi một số mã trong hành động của hành động OpcSaveBilling từ CheckoutController. Tôi không muốn thay đổi mã lõi của NopCommerce vì vậy tôi cần phải cố gắng để vượt qua mã với mã tùy chỉnh của riêng tôi.Cách triển khai Bộ lọc hành động trong NopCommerce

Tôi đã đọc bài viết này để giúp tôi bắt đầu http://www.pronopcommerce.com/overriding-intercepting-nopcommerce-controllers-and-actions. Từ những gì tôi đã đọc, bạn có thể thực thi mã của riêng bạn trước khi một hành động được thực hiện và sau khi một hành động được thực hiện. Nhưng những gì tôi không nhận được là một phần mà bài viết được để mở (mã thực sự cần được thực thi).

Điều tôi muốn cơ bản là cùng chức năng của mã gốc nhưng với một số chỉnh sửa tùy chỉnh. Tôi đã thêm một hộp kiểm trong chế độ xem OnePageCheckout và dựa trên hộp kiểm đó, nó cần phải bỏ qua phần nhập địa chỉ giao hàng trong thanh toán hay không. (Sử dụng địa chỉ thanh toán cho địa chỉ giao hàng)

Tôi đã thêm mã đó vào mã lõi và công việc này và bỏ qua bước (LƯU Ý: Tôi biết mình vẫn cần phải thêm địa chỉ thanh toán làm địa chỉ giao hàng theo cách thủ công) nhưng như tôi đã nói tôi không muốn thay đổi mã trong lõi của NopCommerce nhưng ghi đè lên nó.

Nếu câu hỏi của tôi không dễ hiểu và bạn cần thêm mã hoặc giải thích, tôi rất sẵn lòng cung cấp thêm. Nếu cách tôi làm điều này là không thích hợp cho những gì tôi muốn, tôi sẽ đánh giá cao nếu bạn nói với tôi!

Mã của tôi:

Lớp Filter 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 
    } 
} 

}

đăng ký các lớp học trong DependencyRegistar trong plugin Nop cùng

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

Một ví dụ làm việc với tùy chỉnh mã trong đó. Nhưng đây là hành động cốt lõi.

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

Trả lời

6

Không ai có thể cho bạn biết bạn cần đưa gì vào OnActionExecuting, vì bạn có thể thực hiện rất nhiều việc trong đó.

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 
    } 

Quy tắc chung? Viết bất kỳ mã nào giống như cách bạn sẽ viết Hành động. Tinh chỉnh duy nhất là thay vì trả lại ActionResult, bạn nên đặt filterContext.Result (bạn không thể trả lại bất kỳ thứ gì vì đây là phương thức void).

Ví dụ: cài đặt sau sẽ chuyển hướng đến trang chủ trước khi thực hiện hành động bạn đang ghi đè.

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

Hãy nhớ đây là OnActionExecuting, vì vậy điều này được thực hiện trước khi Tác vụ bạn ghi đè. Và nếu bạn chuyển hướng nó đến một trang khác, nó sẽ không gọi Hành động bạn đang ghi đè. :)

+1

Cảm ơn bạn đã trả lời. Nếu tôi sẽ đặt một chuyển hướng đến một controller + hành động tùy chỉnh trong đó như trong trả lời của bạn, có cách nào để gửi tham số FormCollection mà OpcSaveBilling nhận khi được gọi với chuyển hướng đó để tôi có thể sử dụng nó trong hành động tùy chỉnh của tôi không? –

Các vấn đề liên quan