【问题标题】:Get action from controller using a lambda expression使用 lambda 表达式从控制器获取操作
【发布时间】:2011-07-05 10:45:37
【问题描述】:

我正在尝试创建一个基于控制器名称和操作名称创建 url 的方法。我不想使用魔术字符串,所以我在考虑一种将 lambda 表达式作为参数的方法。

棘手的部分是,我不想在操作方法上指定任何参数。例如,如果我有这个控制器:

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

我想这样调用方法:

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

我想出的方法的签名是:

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

但这并不能解决跳过参数的问题。我的方法只能用这样指定的参数调用:

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

是否可以在控制器上指定动作或方法而无需设置参数?

【问题讨论】:

  • 如果你需要这个,你很可能做错了什么。使用 ASP.NET MVC 扭转手臂
  • 您应该尝试使用此表达式类型Expression&lt;Func&lt;TController, Func&lt;ActionResult&gt;&gt;&gt;,您将能够省略括号c =&gt; c.Index

标签: c# asp.net-mvc expression-trees


【解决方案1】:

除非您的操作方法中有可选或默认参数,否则无法在表达式树中省略参数。因为表达式树可以编译成可运行的代码,表达式仍然由编译器验证,所以它需要是有效的代码 - 方法参数和所有。

正如下面 Dan 的示例,提供默认参数很简单:

public ActionResult Index(int Id = 0)

此外,由于操作方法必须返回某种结果,因此您的表达式应该是 Expression&lt;Func&lt;TController, object&gt;&gt; 类型,这将允许从表达式中定义的方法返回任何类型的对象。

一定要查看MVCContrib

【讨论】:

  • 感谢您的回答,我已经担心这是不可能的。无法将 MvcContrib 用于我的用例,我需要在流畅的接口实现中使用该方法。
  • 我不太同意你的回答。表达式应该是Expression&lt;Func&lt;TController, Func&lt;ActionResult&gt;&gt;&gt; 类型,并且可以很容易地提供 lambda 表达式,而无需提供任何参数,而只是一个动作 referencec =&gt; c.Index。正是 OP 所追求的。
【解决方案2】:

使用T4MVC。这是删除所有魔术字符串并做更多事情的最佳选择

【讨论】:

  • 这是正确的答案。您可能想要所有这些,因为您想摆脱控制器操作的硬编码字符串。 T4MVC 将允许您这样做。
  • 不,我希望它作为我正在编写的组件的流畅界面的一部分。
【解决方案3】:

正如 bdowden 所说,您必须为这些参数提供参数或默认值:

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

此外,如果您使用MVCContrib,这些扩展方法已经存在。 (查看 URLHelperExtentions)。

【讨论】:

    猜你喜欢
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多