ich gelesen habe mehrere Beiträge und Blogs ähnlich wiestark typisierte url Aktion
Delegate-based strongly-typed URL generation in ASP.NET MVC
Aber keiner von ihnen wirklich ganz tun, was ich tun möchte. Zur Zeit habe ich einen hybriden Ansatz wie:
// 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;
}
}
Funktioniert prima, wenn Sie Controller-Methoden sind keine Parameter haben:
public class MyController : Controller
{
public ActionResult MyMethod()
{
return null;
}
public ActionResult MyMethod2(int id)
{
return null;
}
}
Dann kann ich:
Url.Action<MyController>(c => c.MyMethod())
Aber wenn Meine Methode nimmt einen Parameter, dann muss ich einen Wert übergeben (den würde ich nie verwenden):
Url.Action<MyController>(c => c.MyMethod2(-1), new { id = 99 })
So
die Frage ist es eine Möglichkeit, die Erweiterungsmethode zu ändern, nach wie vor den ersten Parameter erfordern ein Verfahren definiert nach Typ werden T
dass tut Prüfung sicherstellen, dass die Rückgabeparameter ist ein ActionResult
ohne tatsächlich einen Parameter angeben, etwas wie:
Url.Action<MyController>(c => c.MyMethod2, new { id = 99 })
so würde dies einen Zeiger auf das Verfahren (wie ein Spiegelbild MethodInfo
) anstelle der Func<>
passieren, so wäre es um Parameter nicht. Wie würde diese Unterschrift aussehen, wenn es möglich wäre?
Mit 'c.MyMethod2' verweisen Sie auf eine Methode _group_, von denen jede etwas anderes zurückgeben kann ... Aber ich bin ziemlich sicher, dass ich Bibliotheken gesehen habe, die dies ermöglichen. Vielleicht können Sie etwas Reflektionszauber machen und 'GetControllerAndAction' einchecken, dass die Methode der Gruppe, die den angegebenen Parametern entspricht, tatsächlich 'ActionResult' zurückgibt. Dies gibt Ihnen zwar nicht die gewünschte Sicherheit bei der Kompilierungszeit, aber Sie sollten keine Non-Action-Methoden als öffentliche Methoden in Ihrem Controller haben. – CodeCaster
'c => c.MyMethod2' kann nicht von' Method Group' in den Nicht-Delegate-Typ 'ActionResult' umgewandelt werden. –
Sie haben natürlich Recht, das funktioniert nur im aktuellen Controller, nicht in der Ansicht. Warum verwenden Sie nicht stattdessen 'c => c.MyMethod2 (99)' (mit 'MethodCallExpression.Arguments', um die Argumente zu erhalten)? – CodeCaster