如何实现在NopCommerce一个Action过滤器 [英] How to implement an Action Filter in NopCommerce

查看:262
本文介绍了如何实现在NopCommerce一个Action过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想改变一些code从CheckoutController的OpcSaveBilling动作一个动作。我不想改变NopCommerce的核心code,所以我需要尽量在此改变code用我自己定制code。

我读过这篇文章,让我开始的http://www.pronopcommerce.com/overriding-intercepting-nopcommerce-controllers-and-actions.从我读过执行之前的操作并执行一个操作之后,你可以执行自己的code什么。但我没有得到的是部分的文章是开放的离开(实际code,需要加以执行)。

我想basicly原来是code,但与一些自定义的调整相同的功能。我在OnePageCheckout视图中添加一个复选框,并在其上​​需要跳过检出或不进入出货编辑部地址一部分复选框为主。 (使用的帐单地址送货地址)

我已经有code加入到核心code和这项工作,并跳过步骤(注:我知道我还需要手动添加帐单邮寄地址送货地址),但就像我说我不想改变NopCommerce的核心,但它覆盖了code。

如果我的问题是不理解,你需要更多的code或解释,我很高兴能提供更多。如果我这样做的方式是不适合我想要什么,我会AP preciate如果你告诉我!

我的code:

该行动过滤器类:

 使用Nop.Web.Controllers;
使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用System.Threading.Tasks;
使用System.Web.Mvc;命名空间Nop.Plugin.Misc.MyProject.ActionFilters
{
类ShippingAddressOverideActionFilter:ActionFilterAttribute,IFilterProvider
{
    公共IEnumerable的<滤光器> GetFilters(ControllerContext controllerContext,ActionDescriptor actionDescriptor)
    {
        如果(controllerContext.Controller是CheckoutController&放大器;&安培; actionDescriptor.ActionName.Equals(OpcSaveBilling,StringComparison.InvariantCultureIgnoreCase))
        {
            返回新的List<滤光器>(){新的过滤器(这一点,FilterScope.Action,0)};
        }
        返回新的List<滤光器>();
    }    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        //什么我摆在这里?所以,我有核心的作用,但在这我自定义调整的code
    }
}

}

注册于DependencyRegistar类在同一个NOP插件

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

在自定义它code的工作示例。但是,这是在芯动作

 公众的ActionResult OpcSaveBilling(的FormCollection形式)
    {
        尝试
        {
            //验证
            VAR车= _workContext.CurrentCustomer.ShoppingCartItems
                。凡(SCI = GT; sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
            。凡(SCI = GT; sci.StoreId == _storeContext.CurrentStore.Id)
                .ToList();
            如果(cart.Count == 0)
                抛出新的异常(您的车是空);            如果(!UseOnePageCheckout())
                抛出新的异常(一结帐页面禁用);            如果((_workContext.CurrentCustomer.IsGuest()及&放大器;!_orderSettings.AnonymousCheckoutAllowed))
                抛出新的异常(匿名结帐是不允许的);            INT billingAddressId = 0;
            int.TryParse(表格[billing_address_id],出billingAddressId);            如果(billingAddressId大于0)
            {
                //现有地址
                VAR地址= _workContext.CurrentCustomer.Addresses.FirstOrDefault(A =&GT; a.Id == billingAddressId);
                如果(地址== NULL)
                    抛出新的异常(地址不能被加载);                _workContext.CurrentCustomer.BillingAddress =地址;
                _customerService.UpdateCustomer(_workContext.CurrentCustomer);
            }
            其他
            {
                //新地址
                VAR模型=新CheckoutBillingAddressModel();
                TryUpdateModel(model.NewAddressBillingNewAddress);
                //验证模型
                TryValidateModel(model.NewAddress);
                如果(!ModelState.IsValid)
                {
                    //模式是无效的。重新显示有错误的形式
                    VAR billingAddressModel = prepareBillingAddressModel(selectedCountryId:model.NewAddress.CountryId);
                    billingAddressModel.NewAddress preselected = TRUE;
                    返回JSON(新
                    {
                        update_section =新UpdateSectionJsonModel()
                        {
                            NAME =账单,
                            HTML = this.RenderPartialViewToString(OpcBillingAddress,billingAddressModel)
                        },
                        wrong_billing_address = TRUE,
                    });
                }                //试图找到具有相同价值观的地址(不重复记录)
                VAR地址= _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.ZipPostal code,model.NewAddress.CountryId);
                如果(地址== NULL)
                {
                    //地址找不到。让我们创建一个新的
                    地址= model.NewAddress.ToEntity();
                    address.CreatedOnUtc = DateTime.UtcNow;
                    //一些验证
                    如果(address.CountryId == 0)
                        address.CountryId = NULL;
                    如果(address.StateProvinceId == 0)
                        address.StateProvinceId = NULL;
                    如果(address.CountryId.HasValue&放大器;&放大器; address.CountryId.Value大于0)
                    {
                        address.Country = _countryService.GetCountryById(address.CountryId.Value);
                    }
                    _workContext.CurrentCustomer.Addresses.Add(地址);
                }
                _workContext.CurrentCustomer.BillingAddress =地址;
                _customerService.UpdateCustomer(_workContext.CurrentCustomer);
            }            //从一个页面查看查看获取复选框的值
            VAR useSameAddress = FALSE;
            Boolean.TryParse(表格[帐单地址相同],出useSameAddress);            //如果检查帐单地址复制到送货地址并跳过结账的送货地址部分
            如果(useSameAddress)
            {
                VAR shippingMethodModel = prepareShippingMethodModel(车);                返回JSON(新
                {
                    update_section =新UpdateSectionJsonModel()
                    {
                        NAME =航运法,
                        HTML = this.RenderPartialViewToString(OpcShippingMethods,shippingMethodModel)
                    },
                    goto_section =SHIPPING_METHOD
                });
            }
            //如果没有检查到收银台去的输入收货地址的一部分
            其他
            {
                如果(cart.RequiresShipping())
                {
                    //需要送货
                    VAR shippingAddressModel = prepareShippingAddressModel(prePopulateNewAddressWithCustomerFields:TRUE);
                    返回JSON(新
                    {
                        update_section =新UpdateSectionJsonModel()
                        {
                            NAME =运费,
                            HTML = this.RenderPartialViewToString(OpcShippingAddress,shippingAddressModel)
                        },
                        goto_section =出货
                    });
                }
                其他
                {
                    //不需要送货
                    _genericAttributeService.SaveAttribute&LT; ShippingOption&GT;(_ workContext.CurrentCustomer,SystemCustomerAttributeNames.SelectedShippingOption,空,_storeContext.CurrentStore.Id);                    //负荷下一步
                    返回OpcLoadStepAfterShippingMethod(车);
                }
            }
        }
        赶上(例外EXC)
        {
            _logger.Warning(exc.Message,EXC,_workContext.CurrentCustomer);
            返回JSON(新{错误= 1,消息= exc.Message});
        }
    }


解决方案

没有人能告诉你,你需要什么就摆在OnActionExecuting,因为有这么多,你可以在里面做。

 公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        //什么我摆在这里?所以,我有核心的作用,但在这我自定义调整的code
    }

经验法则?写任何code怎么样,你会写一个动作。唯一的好办法是,而不是返回的ActionResult,你应该将 filterContext.Result (你可以没有返回值,因为这是一个无效方式)。

例如,设置以下将重定向到首页,即使执行要覆盖行动之前。

  filterContext.Result =新RedirectToRouteResult(主页,NULL);

记住,这是OnActionExecuting,所以这是要覆盖操作之前执行。如果你重定向到另一个网页,它会不会叫你要重写的行动。 :)

I want to change some code in an action of the OpcSaveBilling action from the CheckoutController. I don't want to alter the core code of NopCommerce so i need to try to overide the code with my own custom code.

I've read this article to get me started http://www.pronopcommerce.com/overriding-intercepting-nopcommerce-controllers-and-actions. From what I've read you can execute your own code before an action is executed and after an action is executed. But what I am not getting is the part that the article is leaving open (the actual code that needs to be executed).

What I basicly want is the same function of the original code but with some custom tweaks. I've added a checkbox in the OnePageCheckout view and based on that checkbox it needs to skip the enter shipping addresss part in the checkout or not. (Use the billing address for the shipping address)

I already have that code added to in the core code and this work and skips the step (NOTE: I know I still need to manually add the billing address as shipping address) but like i said i don't want to alter the code in the core of NopCommerce but override of it.

If my question is not understandable and you need more code or explanation I'm happy to provide more. If the way I am doing this is not suitable for what I want, i would appreciate if you tell me!

My code:

The Action Filter class:

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

}

Registered the class in DependencyRegistar in the same Nop plugin

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

A working example with custom code in it. But this is in the core 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 });
        }
    }

解决方案

Nobody can tell you what you need to put in OnActionExecuting, because there is so much you can do in it.

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
    }

Rule of thumb? Write any code like how you'll write an Action. The only tweak is, instead of returning ActionResult, you should set filterContext.Result (you can't return anything as this is a void method).

For example, setting the following will redirect to home page before even executing the action you are overriding.

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

Remember this is OnActionExecuting, so this is executed before the Action you are overriding. And if you redirects it to another page, it'll not call the Action you are overriding. :)

这篇关于如何实现在NopCommerce一个Action过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆