3

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?

2
  • If you need this, you are most likely doing something wrong. Arm twisting with ASP.NET MVC Commented Jul 5, 2011 at 14:46
  • 1
    You should try with this expression type Expression<Func<TController, Func<ActionResult>>> and you'll be able to omit parenthesis c => c.Index. Commented Feb 20, 2014 at 2:52

3 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanx for your answer, I already was afraid this wasn't possible. Can't use MvcContrib for my use case, I needed the method in a fluent interface imlementation.
I wouldn't really agree on your answer. Expression should be of type Expression<Func<TController, Func<ActionResult>>> and one can easily provide lambda expression without providing any parameters but rather just an action reference i.e. c => c.Index. Exactly what OP is after.
3

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

2 Comments

this is the right answer. You probably want all this because you want to get rid of hardcoded string for controllers actions. T4MVC will allow you to do that.
No, I want this as part of a fluent interface for a component I'm writing.
1

As bdowden said, you must provide parameters or defaults for the parameters as such:

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

In addition, if you use MVCContrib these extension methods already exist. (check out URLHelperExtentions).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.