Metodo HTML.ActionLink


249

Diciamo che ho una lezione

public class ItemController:Controller
{
    public ActionResult Login(int id)
    {
        return View("Hi", id);
    }
}

In una pagina che non si trova nella cartella Item, dove ItemControllerrisiede, voglio creare un collegamento al Loginmetodo. Quindi quale Html.ActionLinkmetodo dovrei usare e quali parametri dovrei passare?

In particolare, sto cercando la sostituzione del metodo

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

che è stato ritirato nella recente incarnazione ASP.NET MVC.


17
La documentazione, per chi cerca per esso: msdn.microsoft.com/en-us/library/...
BlueRaja - Danny Pflughoeft

@Danny Grazie, lo stavo cercando su Google quando sono finito qui.
Rei Miyasaka,

Risposte:


491

Penso che quello che vuoi sia questo:

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

Questo utilizza la seguente firma ActionLink del metodo:

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

ASP.NET MVC2

due argomenti sono stati cambiati

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

Questo utilizza la seguente firma ActionLink del metodo:

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

ASP.NET MVC3 +

gli argomenti sono nello stesso ordine di MVC2, tuttavia il valore ID non è più richiesto:

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

Ciò evita di codificare in modo rigido qualsiasi logica di routing nel collegamento.

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

Questo ti darà il seguente output html, supponendo:

  1. article.Title = "Title"
  2. article.ArticleID = 5
  3. hai ancora definito il seguente percorso

. .

routes.MapRoute(
    "Default",     // Route name
    "{controller}/{action}/{id}",                           // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

7
Ma questo non dà un URL come / Item / Login? Id = 5?
Adhip Gupta,

21
La cosa strana è che se perdi l'ultimo parametro, per me va aggiunto? Lunghezza = 8 all'azione corrente
Chris S

32
@Chris S - So che questo è un vecchio post, ma il motivo di? Lunghezza = 8 è perché devi avere un , nullparametro DOPO il tuo new { ... }... perché se controlli i sovraccarichi di quel metodo, sta pensando che i tuoi parametri siano htmlArguments ... non indirizzare argomenti. Per utilizzare il metodo corretto , è necessario utilizzare il metodo che ha routeArguments, htmlArguments.. quindi basta passare a null per l'ultimo htmlArgument. Il primo pezzo di codice in questa risposta ce l'ha. Ho aggiornato questo post in modo da poterlo vedere facilmente (cioè non scorre).
Pure.Krome,

7
Qualcuno ha provato questo con MVC 3? Sembra che le righe ControllerName e ActionMethod nell'esempio sopra siano invertite. Qualcun altro l'ha visto?
Steve Duitsman,

8
In MVC3 non è stata trovata la proprietà id ... Dovrebbe essere utilizzato invece quanto segue:@Html.ActionLink("Text","Action","Controller", new { item.ID }, null)
Gavin Coates

30

Volevo aggiungere alla risposta di Joseph Kingry . Ha fornito la soluzione ma all'inizio non sono riuscito a farlo funzionare neanche e ho ottenuto un risultato proprio come Adhip Gupta. E poi ho capito che il percorso deve esistere in primo luogo e che i parametri devono corrispondere esattamente al percorso. Quindi avevo un ID e quindi un parametro di testo per il mio percorso che doveva essere incluso anche.

Html.ActionLink(article.Title, "Login", "Item", new { id = article.ArticleID, title = article.Title }, null)

4
Questo è proprio ciò di cui avevo bisogno: avevo dimenticato di aggiungere l' argomento null finale . Grazie.
Ian Oxley,

1
Grazie per aver mostrato anche la mappatura dal nome del parametro di rotta (ad es. Nuovo {id = ..., bar = ...}.
William Rose

17

Potresti voler esaminare il RouteLink()metodo, che ti consente di specificare tutto (tranne il testo del collegamento e il nome del percorso) tramite un dizionario.


4
Sarebbe bello vedere un esempio di come ciò risolve il problema; la pagina MSDN ha molti sovraccarichi e sapere cosa cercare potrebbe essere fonte di confusione
Simon Martin

14

Penso che Joseph abbia lanciato il controller e l'azione. Prima arriva l'azione, poi il controller. Questo è un po 'strano, ma l'aspetto della firma.

Giusto per chiarire le cose, questa è la versione che funziona (adattamento dell'esempio di Giuseppe):

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

11

che dire di questo

<%=Html.ActionLink("Get Involved", 
                   "Show", 
                   "Home", 
                   new 
                       { 
                           id = "GetInvolved" 
                       }, 
                   new { 
                           @class = "menuitem", 
                           id = "menu_getinvolved" 
                       }
                   )%>

10
Html.ActionLink(article.Title, "Login/" + article.ArticleID, 'Item") 

Questo avrebbe dovuto essere contrassegnato come la risposta poiché fa esattamente quello che la persona che stava ponendo la domanda stava cercando ... tuttavia noterò che la risposta contrassegnata è andata molto nel dettaglio per l'utente nell'impostazione corretta dei percorsi in varie versioni di MVC.
Indy-Jones,

9

Se vuoi indossare tutti i pantaloni fantasia, ecco come puoi estenderlo per poterlo fare:

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

Dovrai metterlo nello System.Web.Mvcspazio dei nomi:

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;
    }
}

Ciò include due sostituzioni per Route Valuese HTML Attributes, inoltre, tutte le tue visualizzazioni dovrebbero essere aggiunte: @using YourProject.Controllersoppure puoi aggiungerlo al tuoweb.config <pages><namespaces>


1
Sono sorpreso di più non usare questo approccio. Sembra davvero pericoloso usare letterali di stringa ovunque nelle tue viste per rappresentare un controller / azione.
Johnathon Sullinger,

Ho cercato tutto questo per tutta la mia vita
Worthy7 il

Ho provato questo, non ha funzionato. Mi ha dato una stringa vuota alla fine - presumo perché ho parametri nelle mie funzioni.
Degno 7

Puoi pubblicare un github o un altro posto con questo codice in modo che io possa dare un'occhiata e capire perché non funziona per te?
Serj Sagan,

2
Bel uso della parola fantasmi. Non lo vediamo abbastanza.
gdbj,

7

Utilizzare i parametri denominati per la leggibilità e per evitare confusioni.

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

1

Con MVC5 l'ho fatto in questo modo ed è un codice funzionante al 100% ....

@Html.ActionLink(department.Name, "Index", "Employee", new { 
                            departmentId = department.DepartmentID }, null)

Ragazzi, potete avere un'idea da questo ...


0

Questo tipo usa:

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

Pagina principale: Nome del testo Indice: Azione Visualizza Home: HomeController

Base Usa 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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.