【问题标题】:nopCommerce Error: Child actions are not allowed to perform redirect actionsnopCommerce 错误:不允许子操作执行重定向操作
【发布时间】:2015-01-09 07:06:39
【问题描述】:

我正在使用 MVC nopCommerce 并开发自定义插件,该插件会覆盖 HomepageBestSellers 的现有功能(ProductController 的操作归因于 [ChildActionOnly])。

FilterProvider:

namespace Nop.Plugin.Product.BestSellers.Filters
{
    public class BestSellersFilterProvider : IFilterProvider
    {
        private readonly IActionFilter _actionFilter;

        public BestSellersFilterProvider(IActionFilter actionFilter)
        {
            _actionFilter = actionFilter;
        }

        public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
        {
            if (actionDescriptor.ControllerDescriptor.ControllerType == typeof(ProductController) && actionDescriptor.ActionName.Equals("HomepageBestSellers"))
            {
                return new Filter[] 
                { 
                    new Filter(_actionFilter, FilterScope.Action, null)
                };
            }

            return new Filter[] { };
        }
    }
}

Action Filter:

namespace Nop.Plugin.Product.BestSellers.Filters
{
    public class BestSellersFilter : ActionFilterAttribute
    {
        private readonly ISettingService _settingService;
        private readonly IStoreService _storeService;
        private readonly IWorkContext _workContext;

        public BestSellersFilter(ISettingService settingService,
            IStoreService storeService, IWorkContext workContext)
        {
            this._settingService = settingService;
            this._storeService = storeService;
            this._workContext = workContext;
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //load settings for a chosen store scope and ensure that we have 2 (or more) stores
            var storeScope = 0;
            if (_storeService.GetAllStores().Count < 2)
                storeScope = 0;

            var storeId = _workContext.CurrentCustomer.GetAttribute<int>(SystemCustomerAttributeNames.AdminAreaStoreScopeConfiguration);
            var store = _storeService.GetStoreById(storeId);
            storeScope = store != null ? store.Id : 0;

            var bestSellersSettings = _settingService.LoadSetting<BestSellersSettings>(storeScope);

            if (bestSellersSettings.IsBestSellersEnabled)
            {
                filterContext.Result = new RedirectResult("Plugins/BestSellersProducts/PublicInfo");
            }
            else
                base.OnActionExecuting(filterContext);
        }
    }
}

我在 filterContext.Result = new RedirectResult("Plugins/BestSellersProducts/PublicInfo"); 这一行收到以下错误:

Child actions are not allowed to perform redirect actions.

Description: An unhandled exception occurred during the execution of the current web request. 
Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Child actions are not allowed to perform redirect actions.

UPDATE:

  1. 根据答案更改了 BestSellersFilter.cs

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
       var storeScope = 0;
       if (_storeService.GetAllStores().Count < 2)
           storeScope = 0;
    
       var storeId = _workContext.CurrentCustomer.GetAttribute<int>(SystemCustomerAttributeNames.AdminAreaStoreScopeConfiguration);
       var store = _storeService.GetStoreById(storeId);
       storeScope = store != null ? store.Id : 0;
    
       var featuredProductsSettings = _settingService.LoadSetting<FeaturedProductsSettings>(storeScope);
    
       if (featuredProductsSettings.IsFeaturedProductsEnabled)
       {
           var products = _productService.GetAllProductsDisplayedOnHomePage();
    
           BestSellersController objResult = new BestSellersController();
           filterContext.Result = new ContentResult { Content = objResult.PublicInfoPlugin() };
           //base.OnActionExecuting(filterContext);
       }
       else
           base.OnActionExecuting(filterContext);
     }
    
  2. 根据答案更改了 BestSellersController.cs

     public string PublicInfoPlugin()
     {
       var featuredProductsSettings = _settingService.LoadSetting<FeaturedProductsSettings>(_storeContext.CurrentStore.Id);
       if (featuredProductsSettings.IsFeaturedProductsEnabled)
       {
        var products = _productService.GetAllProductsDisplayedOnHomePage();
        //ACL and store mapping
        products = products.Where(p => _aclService.Authorize(p) && _storeMappingService.Authorize(p)).ToList();
        //availability dates
        products = products.Where(p => p.IsAvailable()).ToList();
    
        if (products.Count == 0)
            return "";
    
        var model = PrepareProductOverviewModels(products.Take(featuredProductsSettings.ShowFeaturedProductsNumber)).ToList();
        return RenderPartialViewToString("~/Plugins/Product.FeaturedProducts/Views/ProductFeaturedProducts/PublicInfo.cshtml", model);
       }
    
       return "";
    }
    

现在从 PublicInfoPlugin 方法中的所有私有对象中获取 null 值。

【问题讨论】:

    标签: asp.net-mvc runtime-error nopcommerce


    【解决方案1】:

    将其设置为 ContentResult 而不是 RedirectResult,并将 Content 属性设置为插件操作的输出:

    filterContext.Result = new ContentResult { Content = "Load your plugin's action here"  };
    

    【讨论】:

    • 我试图给filterContext.Result = new ContentResult { Content = "Plugins/BestSellersProducts/PublicInfo" };,但它返回的是相同的字符串(即“Plugins/BestSellersProducts/PublicInfo”)而不是加载它。我猜方法没有调用,它将字符串作为结果内容。如何在此处加载插件操作?
    • 您需要实例化插件的控制器并让操作返回一个字符串而不是 ActionResult。除了返回 Nop.Web.Framework.Controllers.BaseController.RenderPartialViewToString(string viewName, objectModel); 之外,操作中的其他所有内容都保持不变而不是部分视图。如果你的控制器继承自 BaseController,你就会拥有它。
    • 当我按照您的建议使用插件控制器的新实例将其类型 ActionResult 更改为 string 时,插件控制器中的所有其他对象都为空。我的问题更新了,你可以看到更新部分。
    • 您的过滤器将必须实例化控制器的依赖项并将其传递给构造函数。
    • 感谢AndyMcKenna,我现在使用参数化构造函数实例化控制器并获取所有对象值。但现在问题是我在Nop.Web.Framework.Controllers.BaseController.RenderPartialViewToString(string viewName, object model)ViewEngineResult viewResult = System.Web.Mvc.ViewEngines.Engines.FindPartialView(this.ControllerContext, viewName); 线上遇到错误Value cannot be null. Parameter name: controllerContext。我不知道,为什么它给出了空上下文?
    猜你喜欢
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    相关资源
    最近更新 更多