Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get action from controller using a lambda expression

I'm trying to create a method which creates a url based on the controllername and the actionname. I don't want to use magic strings, so I was thinking about a method taking a lambda expression as a parameter.

The tricky part is, I don't want to specify any parameters on the action method. So for instance if I have this controller:

public class HomeController : IController
{
  public Index(int Id)
  {
     ..
  }
}

I would like to call the method like this:

CreateUrl<HomeController>(x=>x.Index);

The signature of the method I've come up with is:

public string CreateUrl<TController>(Expression<Action<TController>> action) where TController : IController

But this does not solve the problem of skipping the parameters. My method can only be called with the parameter specfied like this:

CreateUrl<HomeController>(x=>x.Index(1));

Is it possible to specify an action or method on a controller without having to set the parameters?

like image 220
Robin van der Knaap Avatar asked Feb 23 '23 16:02

Robin van der Knaap


2 Answers

It is not possible to omit the parameters with an expression tree unless you have optional or default parameters within your action methods. Because expression trees can be compiled into runnable code, the expression is still validated by the compiler so it needs to be valid code - method parameters and all.

As in Dan's example below, supplying a default parameter is as simple as:

public ActionResult Index(int Id = 0)

Additionally, since action methods have to return some sort of result, your Expression should be of type Expression<Func<TController, object>> , which will allow for any type of object to be returned from the method defined in the expression.

Definitely check out MVCContrib.

like image 107
bdowden Avatar answered Mar 08 '23 01:03

bdowden


Use T4MVC. This is best option to remove all magic strings and do much more

like image 31
archil Avatar answered Mar 08 '23 01:03

archil