Override Existing Controller & Action in Nop Version 4.0

2 years ago
Hi

I want to Override product Controller (ProductDetail action in that) in nop version 4.

The problem is Route provider. As I want to route to my new product controller (ProductDetail action in that) over existing product controller.

Route Provider:

routeBuilder.MapLocalizedRoute("Product", "{SeName}", 
                new { controller = "Product", action = "ProductDetails" });

The error is:
AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied:

Nop.Web.Themes.NewPro.Controllers.ProductController.ProductDetails (Nop.Web)
Nop.Web.Controllers.ProductController.ProductDetails (Nop.Web)

Thanks in advance
2 years ago
This is working with 3.90 but not try 4.0 yet.

But you can try if working than well and good.

May be it would helpful to you.

https://nop-station.com/how-to-override-nopcommerce-generic-route-from-a-plugin.

Also go through.

https://www.nopcommerce.com/boards/t/34085/override-productdetail-route.aspx
2 years ago
sk5202 wrote:
This is working with 3.90 but not try 4.0 yet.

But you can try if working than well and good.

May be it would helpful to you.

https://nop-station.com/how-to-override-nopcommerce-generic-route-from-a-plugin.

Also go through.

https://www.nopcommerce.com/boards/t/34085/override-productdetail-route.aspx



Thanks for the reply!

For me also working in 3.90 but not working in 4.0. Kindly find me an alternate
2 years ago
Does anyone find a solution for this for nopCommerce 4.0?
1 year ago
Any solution for nopCommerce 4.0 and 4.1 ?
Thanks
1 year ago
Any solution for nopCommerce 4.0 and 4.1 ?
Thanks
1 year ago
Have you tried using a Route attribute on your overriding action in 4.1?

[Route( "AddProductsToCard/detail/{productId}/{shoppingCartTypeId}", Name = "AddProductsToCardOverride", priority = Int32.MaxValue )]
public override IActionResult AddProductsToCart_Detail(int productId, int shoppingCartTypeId, IFormCollection form)
{

  // do your thing here.
  // return whatever you like or continue to base action


  return base.AddProductsToCart_Detail(productId, shoppingCartTypeId, form);

}

Not tested and different type of action, but it might help. make sure you add the name into the attribute or you'll get a duplication error at runtime.
1 year ago
I am also having this problem with 4.1.  I inherited from CustomerController and only overridden the Edit action.  The problem is that even when the List action is called, I get the same ambiguous exception as the original poster did.

Any suggestions?
1 year ago
You can use Action Filter. For 4.1

Create a Custom Action Filter:

public class CustomActionFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {

            var actionName = ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ActionName;
            var controllerName = ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ControllerName;
            if (!string.IsNullOrEmpty(controllerName) && !string.IsNullOrEmpty(actionName) && context.Controller is Web.Controllers.ProductController)
            {
                switch (controllerName)
                {
                    case "Product":
                        context.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "CustomProduct", action = "ProductDetails", productId = context.ActionArguments["productId"] }));
                        break;

                }
            }
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {

        }

    }


Add your action filter to CustomStartup : INopStartup

 services.AddMvc(options =>
            {
                //an instant  
                options.Filters.Add(new CustomActionFilter());
                //By the type  
                options.Filters.Add(typeof(CustomActionFilter));
            });


Then Add Route Request in CustomGenericPathRoute : GenericPathRoute

case "customproduct":
                    currentRouteData.Values["controller"] = "CustomProduct";
                    currentRouteData.Values["action"] = "ProductDetails";
                    currentRouteData.Values["productid"] = urlRecord.EntityId;
                    currentRouteData.Values["SeName"] = urlRecord.Slug;
                    break;


Then register your route in CustomGenericUrlRouteProvider : IRouteProvider

//Product
            routeBuilder.CustomMapGenericPathRoute("Plugin.Misc.YourPlugin.ProductDetails", "{GenericSeName}",
                 new { controller = "CustomProduct", action = "ProductDetails" });


make sure in your CustomGenericUrlRouteProvider
public int Order
        {
            get { return int.MaxValue; }
        }


Otherwise url will be without slug.
1 year ago
Check this:

https://stackoverflow.com/questions/51349537/overriding-does-not-work-on-virtual-method-in-asp-net-core-mvc