che ho letto più post e blog simili afortemente tipizzato azione url
Delegate-based strongly-typed URL generation in ASP.NET MVC
ma nessuno di loro davvero fanno quello che mi piacerebbe fare. Attualmente ho un approccio ibrido come:
// shortened for Brevity
public static Exts
{
public string Action(this UrlHelper url,
Expression<Func<T, ActionResult>> expression)
where T : ControllerBase
{
return Exts.Action(url, expression, null);
}
public string Action(this UrlHelper url,
Expression<Func<T, ActionResult>> expression,
object routeValues)
where T : ControllerBase
{
string controller;
string action;
// extension method
expression.GetControllerAndAction(out controller, out action);
var result = url.Action(action, controller, routeValues);
return result;
}
}
Funziona grande se siete metodi del controllore non hanno alcun parametro:
public class MyController : Controller
{
public ActionResult MyMethod()
{
return null;
}
public ActionResult MyMethod2(int id)
{
return null;
}
}
allora posso:
Url.Action<MyController>(c => c.MyMethod())
Ma se il mio metodo accetta un parametro, quindi devo passare un valore (che non utilizzerei mai):
Url.Action<MyController>(c => c.MyMethod2(-1), new { id = 99 })
Quindi la domanda c'è un modo per cambiare il metodo di estensione per richiedere ancora il primo parametro da un metodo definito dal tipo T
che fa controllo per assicurarsi che il parametro di ritorno è un ActionResult
senza in realtà specificare un parametro, qualcosa come:
Url.Action<MyController>(c => c.MyMethod2, new { id = 99 })
quindi questo passerebbe un puntatore al metodo (come una riflessione MethodInfo
) invece del Func<>
, quindi non sarebbe preoccuparsi parametri. Come sarebbe quella firma se fosse possibile?
Con 'c.MyMethod2' stai indicando un metodo _group_, ognuno dei quali può restituire qualcos'altro ... Ma sono abbastanza sicuro di aver visto librerie che lo abilitano. Magari puoi fare qualche riflessione magica e controllare in 'GetControllerAndAction' che il metodo del gruppo che corrisponde ai parametri forniti restituisca effettivamente' ActionResult'. Questo non ti darà esattamente la sicurezza in fase di compilazione che stai cercando, ma non dovresti comunque avere metodi non di azione come metodi pubblici nel tuo controller. – CodeCaster
'c => c.MyMethod2' non può essere lanciato da' Metodo gruppo' a non delegato tipo 'ActionResult'. –
Ovviamente hai ragione, funzionerà solo nel controller corrente, non nella vista. Perché non stai usando 'c => c.MyMethod2 (99)' invece (usando 'MethodCallExpression.Arguments' per ottenere gli argomenti)? – CodeCaster