Nehmen wir an, ich habe eine Klasse
public class ItemController:Controller
{
public ActionResult Login(int id)
{
return View("Hi", id);
}
}
Auf einer Seite, die sich nicht im Ordner Item befindet, in dem sich ItemController
befindet, möchte ich einen Link zur Methode Login
erstellen. Welche Html.ActionLink
Methode soll ich verwenden und welche Parameter soll ich übergeben?
Konkret suche ich den Ersatz der Methode
Html.ActionLink(article.Title,
new { controller = "Articles", action = "Details",
id = article.ArticleID })
das ist in der kürzlichen ASP.NET MVC-Inkarnation zurückgezogen worden.
Ich denke, was Sie wollen, ist Folgendes:
Html.ActionLink(article.Title,
"Login", // <-- Controller Name.
"Item", // <-- ActionMethod
new { id = article.ArticleID }, // <-- Route arguments.
null // <-- htmlArguments .. which are none. You need this value
// otherwise you call the WRONG method ...
// (refer to comments, below).
)
Hierbei wird die folgende ActionLink-Signaturmethode verwendet:
public static string ActionLink(this HtmlHelper htmlHelper,
string linkText,
string controllerName,
string actionName,
object values,
object htmlAttributes)
zwei Argumente wurden vertauscht
Html.ActionLink(article.Title,
"Item", // <-- ActionMethod
"Login", // <-- Controller Name.
new { id = article.ArticleID }, // <-- Route arguments.
null // <-- htmlArguments .. which are none. You need this value
// otherwise you call the WRONG method ...
// (refer to comments, below).
)
Hierbei wird die folgende ActionLink-Signaturmethode verwendet:
public static string ActionLink(this HtmlHelper htmlHelper,
string linkText,
string actionName,
string controllerName,
object values,
object htmlAttributes)
Argumente sind in derselben Reihenfolge wie MVC2, der ID-Wert wird jedoch nicht mehr benötigt:
Html.ActionLink(article.Title,
"Item", // <-- ActionMethod
"Login", // <-- Controller Name.
new { article.ArticleID }, // <-- Route arguments.
null // <-- htmlArguments .. which are none. You need this value
// otherwise you call the WRONG method ...
// (refer to comments, below).
)
Auf diese Weise wird vermieden, dass eine Routing-Logik in die Verbindung festcodiert wird.
<a href="/Item/Login/5">Title</a>
Dies gibt Ihnen die folgende HTML-Ausgabe, vorausgesetzt:
article.Title = "Title"
article.ArticleID = 5
. .
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
Ich wollte hinzufügen zu Joseph Kingrys Antwort . Er lieferte die Lösung, aber zuerst konnte ich es auch nicht zum Laufen bringen und bekam ein Ergebnis wie Adhip Gupta. Und dann wurde mir klar, dass die Route an erster Stelle existieren muss und die Parameter genau mit der Route übereinstimmen müssen. Ich hatte also eine ID und dann einen Textparameter für meine Route, der auch einbezogen werden musste.
Html.ActionLink(article.Title, "Login", "Item", new { id = article.ArticleID, title = article.Title }, null)
Vielleicht möchten Sie sich die RouteLink()
-Methode ansehen. Mit dieser Methode können Sie alles (außer den Linktext und den Routennamen) über ein Wörterbuch angeben.
Ich denke, dass Joseph den Controller und die Aktion umgedreht hat. Zuerst kommt die Aktion, dann der Controller. Das ist etwas seltsam, aber wie die Signatur aussieht.
Nur um die Dinge zu verdeutlichen, ist dies die Version, die funktioniert (Anpassung von Josephs Beispiel):
Html.ActionLink(article.Title,
"Login", // <-- ActionMethod
"Item", // <-- Controller Name
new { id = article.ArticleID }, // <-- Route arguments.
null // <-- htmlArguments .. which are none
)
was ist damit?
<%=Html.ActionLink("Get Involved",
"Show",
"Home",
new
{
id = "GetInvolved"
},
new {
@class = "menuitem",
id = "menu_getinvolved"
}
)%>
Html.ActionLink(article.Title, "Login/" + article.ArticleID, 'Item")
Wenn Sie alle ausgefallenen Hosen tragen möchten, können Sie sie wie folgt erweitern:
@(Html.ActionLink<ArticlesController>(x => x.Details(), article.Title, new { id = article.ArticleID }))
Sie müssen dies in den Namensraum System.Web.Mvc
einfügen:
public static class MyProjectExtensions
{
public static MvcHtmlString ActionLink<TController>(this HtmlHelper htmlHelper, Expression<Action<TController>> expression, string linkText)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);
var link = new TagBuilder("a");
string actionName = ExpressionHelper.GetExpressionText(expression);
string controllerName = typeof(TController).Name.Replace("Controller", "");
link.MergeAttribute("href", urlHelper.Action(actionName, controllerName));
link.SetInnerText(linkText);
return new MvcHtmlString(link.ToString());
}
public static MvcHtmlString ActionLink<TController, TAction>(this HtmlHelper htmlHelper, Expression<Action<TController, TAction>> expression, string linkText, object routeValues)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);
var link = new TagBuilder("a");
string actionName = ExpressionHelper.GetExpressionText(expression);
string controllerName = typeof(TController).Name.Replace("Controller", "");
link.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));
link.SetInnerText(linkText);
return new MvcHtmlString(link.ToString());
}
public static MvcHtmlString ActionLink<TController>(this HtmlHelper htmlHelper, Expression<Action<TController>> expression, string linkText, object routeValues, object htmlAttributes) where TController : Controller
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);
var attributes = AnonymousObjectToKeyValue(htmlAttributes);
var link = new TagBuilder("a");
string actionName = ExpressionHelper.GetExpressionText(expression);
string controllerName = typeof(TController).Name.Replace("Controller", "");
link.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));
link.MergeAttributes(attributes, true);
link.SetInnerText(linkText);
return new MvcHtmlString(link.ToString());
}
private static Dictionary<string, object> AnonymousObjectToKeyValue(object anonymousObject)
{
var dictionary = new Dictionary<string, object>();
if (anonymousObject == null) return dictionary;
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(anonymousObject))
{
dictionary.Add(propertyDescriptor.Name, propertyDescriptor.GetValue(anonymousObject));
}
return dictionary;
}
}
Dies beinhaltet zwei Überschreibungen für Route Values
und HTML Attributes
. Außerdem müssten alle Ihre Ansichten Folgendes hinzufügen: @using YourProject.Controllers
oder Sie können es zu Ihrem web.config <pages><namespaces>
hinzufügen.
Verwenden Sie benannte Parameter zur besseren Lesbarkeit und zur Vermeidung von Verwechslungen.
@Html.ActionLink(
linkText: "Click Here",
actionName: "Action",
controllerName: "Home",
routeValues: new { Identity = 2577 },
htmlAttributes: null)
Mit MVC5 habe ich es so gemacht und es ist 100% funktionierender Code ....
@Html.ActionLink(department.Name, "Index", "Employee", new {
departmentId = department.DepartmentID }, null)
Ihr könnt euch ein Bild davon machen ...