我正在'泛化'.NET 3.5 MVC應用程序中的一些代碼,並且偶然發現了一個問題。如何傳遞一個委託來創建一個表達式樹,這是一個MethodCallExpression
背景
我有一個SomeController類的一些行動:
public ActionResult Renew(string qualification, int tierId) { ... }
public ActionResult Reinstate(string qualification, int tierId) { ... }
public ActionResult Withdraw(string qualification, int tierId) { ... }
在我使用的是強類型的擴展輔助方法來創建一個ActionLink的視圖(這個通用的方法來自Microsoft.Web.Mvc.dll
)。樣的用途是
Html.ActionLink<SomeController>(c=>c.Renew(Model.Qualification, Model.TierId),"Renew")
只有我有一個定義的方法調用的表達式的視圖屬性,所以我可以這樣做:
Html.ActionLink(Model.Action,"Renew")
在視圖模型的Action屬性具有以下簽名
public Expression<Action<SomeController>> Action { get; set; }
當我在一個控制器動作我可以使用下面的代碼創建視圖:
model.Action = c => c.Renew(dto.Qualification.Name, t.Id)
方法
到目前爲止好,所有的強類型的工作很好,但這是我的問題開始的地方。我希望能夠用傳入組裝視圖模型的方法的參數替換對c => c.Renew(dto.Qualification.Name, t.Id)
的顯式調用。
我希望執行以下操作:
private SomeViewModel CreateViewModel(SomeDto dto, Tier t, Func<string, int, ActionResult>> actionToCall) {
return new SomeViewModel {
...
Action = a => actionToCall(dto.Qualification.Name, t.Id),
}
}
,然後使用此方法來構建模型,並通過適當的控制器的動作作爲一個參數
var model = CreateViewModel(dto,tier,this.Reinstate)
問題
該解決方案編譯,但是當我開始渲染ActionLink時,我得到一個期望,因爲表達式傳入作爲動作不是MethodCallExpression
類型。該異常由View中的Html.ActionLink擴展方法拋出。
謝謝。我會放棄它。 你能不能通過參數建立一個表達式樹? – mfloryan 2010-06-23 14:14:01
@mfloryan:您當然可以構建一個調用作爲參數傳入的委託的表達式樹,但表達式樹將具有引用該參數的InvocationExpression。這聽起來像ActionLink期待一個MethodCallExpression。 – Quartermeister 2010-06-25 13:26:23