5

I am adapting an open source project (NopCommerce). It is a great software and supports extensibility using plugins. For one plugin, I would like to add information to a view, to do that, I want to inherit from the Controller and override the actions I need to change. So this is my controller:

public class MyController : OldController{
//stuff

public new ActionResult Product(int productId)
{
 //Somestuff
}

}

I changed the route from my plugin, but when this action get called I get the following error:

The current request for action 'Product' on controller type 'MyController' is ambiguous between the following action methods: System.Web.Mvc.ActionResult Product(Int32) on type MyPlugin System.Web.Mvc.ActionResult Product(Int32) on type OldController

Is there any way I can override this method? (ps: I can't use the override keyword because it is not marked as virtual, abstract or override in the OldController)

thanks, Oscar

AndyMcKenna
  • 2,607
  • 3
  • 26
  • 35
JSBach
  • 4,679
  • 8
  • 51
  • 98
  • 1
    How about not _deriving_ from `OldController` but instead providing all the `OldController` methods wrapped in your `MyController` class (kind of similar to the [Proxy pattern](http://www.dofactory.com/Patterns/PatternProxy.aspx#_self1)) – Uwe Keim Feb 20 '13 at 02:19
  • If it were marked virtual would it have worked? I'd have thought in a perverse way that what you had would have worked – Rikon Feb 20 '13 at 02:22
  • what do you want to achieve that is not easily extensible from current Controller class? – Dave Alperovich Feb 20 '13 at 02:23
  • @Rikon I don't know, but I would not like to change the source code in order to be able to update to new releases ;) – JSBach Feb 20 '13 at 02:37
  • @DaveA I need custom information from the product that my plugin inserts (for instance: statistics, calculated price according to each user - in this system, each user would have a different price depending on their characteristics). So I would have to load this info from the controller and add it to the model which is sent to the view – JSBach Feb 20 '13 at 02:39
  • @Oscar, so far everything you mentioned sounds do-able by extending the existing Controller. Maybe I need more detail... – Dave Alperovich Feb 20 '13 at 02:44
  • @Oscar I agree... I was really riding this question from curiosity... I just wondered if it would work... But I agree w/ you – Rikon Feb 20 '13 at 02:45
  • @DaveA What do you mean by "extending the existing controller"? You mean changing the controller source code? Is this is the case, the problem is that I do not want to change the software's code – JSBach Feb 20 '13 at 02:49

3 Answers3

6

If OldController's method is few, Redeclare like this.

public class MyController : Controller 
{
    private OldController old = new OldController();

    // OldController method we want to "override"
    public ActionResult Product(int productid)
    {
        ...
        return View(...);
    }

    // Other OldController method for which we want the "inherited" behavior
    public ActionResult Method1(...)
    {
        return old.Method1(...);
    }
}
Kirk Woll
  • 76,112
  • 22
  • 180
  • 195
ebattulga
  • 10,774
  • 20
  • 78
  • 116
  • 1
    Yes, this is a way out that sounds good, @Uwe Kleim proposed it in the comments. DaveA sounds as he has a very good insight, so I will check his idea before trying this one :) – JSBach Feb 20 '13 at 02:48
  • 1
    @Oscar, depending on your needs, I would have suggested inheriting a from the Controller class exactly the way ebattulga has. This is the approach you're looking for! ;) – Dave Alperovich Feb 20 '13 at 02:56
0

sure, "do a F12" on the controller and look at the items marked virtual

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (Request.Headers.TryGetValue("myHeader", out var value))
        {
            HashId = hashid.ToString();
        }
        base.OnActionExecuting(context);
    }
Walter Verhoeven
  • 3,867
  • 27
  • 36
0

Just Change

    public class MyController : OldController{
    //stuff

        public new ActionResult Product(int productId)
        {
        //Somestuff
        }
    }

to

    public class MyController : OldController{
    //stuff

        public override ActionResult Product(int productId)
        {
        //Somestuff
        }
    }
lkosidlo
  • 1
  • 1