HTML.ActionLink-Methode

249

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 "Element" befindet, auf der sich ItemControllerbefindet, möchte ich einen Link zur LoginMethode erstellen . Also , welche Html.ActionLinkMethode soll ich verwenden und welche Parameter sollte ich übergeben?

Insbesondere suche ich den Ersatz der Methode

Html.ActionLink(article.Title,
    new { controller = "Articles", action = "Details",
          id = article.ArticleID })

Dies wurde in der letzten ASP.NET MVC-Inkarnation eingestellt.

Graviton
quelle
17
Dokumentation, für alle, die danach suchen: msdn.microsoft.com/en-us/library/…
BlueRaja - Danny Pflughoeft
@Danny Danke, habe bei Google danach gesucht, als ich hier gelandet bin.
Rei Miyasaka

Antworten:

491

Ich denke, was Sie wollen, ist Folgendes:

ASP.NET MVC1

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).
                )

Dies verwendet die folgende ActionLink-Signaturmethode:

public static string ActionLink(this HtmlHelper htmlHelper, 
                                string linkText,
                                string controllerName,
                                string actionName,
                                object values, 
                                object htmlAttributes)

ASP.NET MVC2

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).
                )

Dies verwendet die folgende ActionLink-Signaturmethode:

public static string ActionLink(this HtmlHelper htmlHelper, 
                                string linkText,
                                string actionName,
                                string controllerName,
                                object values, 
                                object htmlAttributes)

ASP.NET MVC3 +

Argumente befinden sich 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).
                )

Dadurch wird vermieden, dass Routing-Logik in die Verbindung hartcodiert wird.

 <a href="/Item/Login/5">Title</a> 

Dies gibt Ihnen die folgende HTML-Ausgabe, vorausgesetzt:

  1. article.Title = "Title"
  2. article.ArticleID = 5
  3. Sie haben noch die folgende Route definiert

. .

routes.MapRoute(
    "Default",     // Route name
    "{controller}/{action}/{id}",                           // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);
Joseph Kingry
quelle
7
Aber gibt dies nicht eine URL wie / Item / Login aus? Id = 5?
Adhip Gupta
21
Was seltsam ist, wenn Sie den letzten Parameter verpassen, der für mich angehängt wird? Länge = 8 an die aktuelle Aktion
Chris S
32
@Chris S - Ich weiß, dass dies ein alter Beitrag ist, aber der Grund für die? Length = 8 ist, dass Sie einen , nullParameter NACH Ihrem new { ... }... benötigen, denn wenn Sie die Überladungen dieser Methode überprüfen, denken Sie, dass Ihre Parameter htmlArguments sind ... keine Argumente weiterleiten. Um die richtige Methode zu verwenden, müssen Sie die Methode verwenden, die routeArguments, htmlArguments.. hat . Geben Sie also für diesen letzten einfach null ein htmlArgument. Der erste Code in dieser Antwort enthält ihn. Ich habe diesen Beitrag aktualisiert, damit Sie ihn leicht sehen können (dh er scrollt nicht).
Pure.Krome
7
Hat jemand dies mit MVC 3 versucht? Es scheint, dass die Zeilen ControllerName und ActionMethod im obigen Beispiel umgedreht sind. Hat das noch jemand gesehen?
Steve Duitsman
8
In MVC3 wird die id-Eigenschaft nicht gefunden ... stattdessen sollte Folgendes verwendet werden:@Html.ActionLink("Text","Action","Controller", new { item.ID }, null)
Gavin Coates
30

Ich wollte Joseph Kingrys Antwort ergänzen . Er lieferte die Lösung, aber zuerst konnte ich sie auch nicht zum Laufen bringen und erzielte ein Ergebnis wie Adhip Gupta. Und dann wurde mir klar, dass die Route überhaupt existieren muss und die Parameter genau mit der Route übereinstimmen müssen. Also hatte ich eine ID und dann einen Textparameter für meine Route, der ebenfalls enthalten sein musste.

Html.ActionLink(article.Title, "Login", "Item", new { id = article.ArticleID, title = article.Title }, null)
Jeff Widmer
quelle
4
Dies ist genau das, was ich brauchte - ich hatte vergessen, das letzte Null- Argument hinzuzufügen . Vielen Dank.
Ian Oxley
1
Vielen Dank, dass Sie auch die Zuordnung vom Namen des Routenparameters angezeigt haben (z. B. neu {id = ..., bar = ...}.
William Rose
17

Vielleicht möchten Sie sich die RouteLink()Methode ansehen. Mit dieser Methode können Sie alles (außer dem Linktext und dem Routennamen) über ein Wörterbuch angeben.

Gehackt
quelle
4
Es wäre toll, ein Beispiel dafür zu sehen, wie das Problem gelöst wird. Die MSDN-Seite hat viele Überladungen und zu wissen, wonach zu suchen ist, könnte verwirrend sein
Simon Martin
14

Ich denke, dass Joseph Controller und Action umgedreht hat. Zuerst kommt die Aktion, dann der Controller. Das ist etwas seltsam, aber wie die Signatur aussieht.

Nur um die Dinge zu klären, ist dies die Version, die funktioniert (Adaption von Josephs Beispiel):

Html.ActionLink(article.Title, 
    "Login",  // <-- ActionMethod
    "Item",   // <-- Controller Name
    new { id = article.ArticleID }, // <-- Route arguments.
    null  // <-- htmlArguments .. which are none
    )
agez
quelle
11

was ist damit?

<%=Html.ActionLink("Get Involved", 
                   "Show", 
                   "Home", 
                   new 
                       { 
                           id = "GetInvolved" 
                       }, 
                   new { 
                           @class = "menuitem", 
                           id = "menu_getinvolved" 
                       }
                   )%>
Hasan
quelle
10
Html.ActionLink(article.Title, "Login/" + article.ArticleID, 'Item") 
Adhip Gupta
quelle
Dies hätte wirklich als Antwort markiert werden müssen, da es genau das tut, wonach die Person, die die Frage gestellt hat, gesucht hat ... Ich werde jedoch feststellen, dass die markierte Antwort für den Benutzer sehr detailliert war, als er Routen in verschiedenen Versionen korrekt eingerichtet hat von MVC.
Indy-Jones
9

Wenn Sie alle ausgefallenen Hosen tragen möchten, können Sie sie folgendermaßen erweitern, um dies zu tun:

@(Html.ActionLink<ArticlesController>(x => x.Details(), article.Title, new { id = article.ArticleID }))

Sie müssen dies in den System.Web.MvcNamespace 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 umfasst zwei Überschreibungen für Route Valuesund HTML Attributesaußerdem müssen alle Ihre Ansichten hinzugefügt werden: @using YourProject.Controllersoder Sie können sie zu Ihren hinzufügenweb.config <pages><namespaces>

Serj Sagan
quelle
1
Ich bin überrascht, dass mehr diesen Ansatz nicht verwenden. Es scheint wirklich gefährlich, in Ihren Ansichten überall String-Literale zu verwenden, um einen Controller / eine Aktion darzustellen.
Johnathon Sullinger
Ich habe
Versuchte dies, funktionierte nicht. Hat mir am Ende eine leere Zeichenfolge gegeben - ich nehme an, weil ich Parameter in meinen Funktionen habe.
Worthy7
Können Sie einen Github oder einen anderen Ort mit diesem Code posten, damit ich nachsehen kann, warum er bei Ihnen nicht funktioniert?
Serj Sagan
2
Gute Verwendung des Wortes Fancypants. Das sehen wir nicht genug.
GDBJ
7

Verwenden Sie benannte Parameter, um die Lesbarkeit zu verbessern und Verwirrungen zu vermeiden.

@Html.ActionLink(
            linkText: "Click Here",
            actionName: "Action",
            controllerName: "Home",
            routeValues: new { Identity = 2577 },
            htmlAttributes: null)
Guneysos
quelle
1

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 ...

Sohail Malik
quelle
0

Dieser Typ verwendet:

@ Html.ActionLink ("MainPage", "Index", "Home")

Hauptseite: Name des Textes Index: Aktion Ansicht Startseite: HomeController

Basis Verwenden Sie ActionLink

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>_Layout</title>
    <link href="@Url.Content("~/Content/bootsrap.min.css")" rel="stylesheet" type="text/css" />
</head>
<body>
    <div class="container">
        <div class="col-md-12">
            <button class="btn btn-default" type="submit">@Html.ActionLink("AnaSayfa","Index","Home")</button>
            <button class="btn btn-default" type="submit">@Html.ActionLink("Hakkımızda", "Hakkimizda", "Home")</button>
            <button class="btn btn-default" type="submit">@Html.ActionLink("Iletişim", "Iletisim", "Home")</button>
        </div> 
        @RenderBody()
        <div class="col-md-12" style="height:200px;background-image:url(/img/footer.jpg)">

        </div>
    </div>
</body>
</html>

Serdin çelik
quelle