Incluso un tag anchor in un ASP.NET MVC Html.ActionLink


151

In ASP.NET MVC, sto cercando di creare un collegamento che includa un tag di ancoraggio (vale a dire, indirizzare l'utente a una pagina e una sezione specifica della pagina).

L'URL che sto cercando di creare dovrebbe essere simile al seguente:

<a href="/category/subcategory/1#section12">Title for a section on the page</a>

Il mio routing è impostato con lo standard:

routes.MapRoute("Default", "{controller}/{action}/{categoryid}"); 

La sintassi del link azione che sto usando è:

<%foreach (Category parent in ViewData.Model) { %>
<h3><%=parent.Name %></h3>
<ul>
<%foreach (Category child in parent.SubCategories) { %>
    <li><%=Html.ActionLink<CategoryController>(x => x.Subcategory(parent.ID), child.Name) %></li>
<%} %>
</ul>
<%} %>

Il mio metodo controller è il seguente:

public ActionResult Subcategory(int categoryID)
{
   //return itemList

   return View(itemList);
}

Quanto sopra restituisce correttamente un URL come segue:

<a href="/category/subcategory/1">Title for a section on the page</a>

Non riesco a capire come aggiungere la parte # section12 . La parola "sezione" è solo la convenzione che sto usando per spezzare le sezioni di pagina, e il 12 è l'ID della sottocategoria, cioè child.ID.

Come posso fare questo?

Risposte:


97

Probabilmente costruirò il collegamento manualmente, in questo modo:

<a href="<%=Url.Action("Subcategory", "Category", new { categoryID = parent.ID }) %>#section12">link text</a>

20
Dovrebbe davvero usare i sovraccarichi per ActionLink come descritto da @ Brad Wilson.
mattruma,

18
@mattruma scusa non sono d'accordo. BACIO. Perché avere un membro pieno di parametri, alcuni dei quali vengono lasciati come null, quando puoi semplicemente dichiararlo esplicitamente. Chiunque può vedere cosa significa quanto sopra per cui la risposta di Brad è contorta e richiede di scavare nell'intellisense. Troppi parametri è un modello anti riconosciuto. C2.com/cgi/wiki?TooManyParameters
Ed Blackburn

2
Sono d'accordo. Entrambi i metodi funzionano, ma poiché il modo in cui i frammenti sono specificati negli URL non cambierà nel prossimo futuro, penso che in questo modo sia effettivamente più leggibile e più chiaro nel suo intento. Se necessario, è ancora possibile estendere l' oggetto Urlo Htmlcon un metodo personalizzato che include un modo semplice per aggiungere una stringa di frammento.
LorenzCK,

282

Esistono sovraccarichi di ActionLink che accettano un parametro di frammento . Passando "section12" come frammento otterrai il comportamento che stai cercando.

Ad esempio, chiamando il metodo LinkExtensions.ActionLink (HtmlHelper, String, String, String, String, String, String, Object, Object) :

<%= Html.ActionLink("Link Text", "Action", "Controller", null, null, "section12-the-anchor", new { categoryid = "blah"}, null) %>

1
Questi sovraccarichi fanno parte di una libreria di estensioni? Non mi sembra di averli.
granata,

Esistono due: stringa statica pubblica ActionLink (questo htmlHelper htmlHelper, string linkText, string actionName, string controllerName, protocollo string, string hostName, frammento di stringa, oggetto routeValues, oggetto htmlAttributes); stringa statica pubblica ActionLink (questo htmlHelper htmlHelper, string linkText, string actionName, string controllerName, protocollo string, string hostName, frammento stringa, RouteValueDictionary routeValues, IDictionary <stringa, oggetto> htmlAttributes);
Brad Wilson,

11
Questa dovrebbe essere la risposta.
Rubens Mariuzzo,

1
I sovraccarichi di Html.ActionLink che consentono la specifica di un'ancora passando il frammento, ti costringono a passare il controller per nome. Non mi piace. Se il nome del controller non è corretto, si verificheranno eccezioni di runtime anziché errori di compilazione.
R. Schreurs,

1
@RobertMcKee se il testo del tuo link è più di un semplice testo, quindi Html.ActionLink()non funzionerebbe in nessuno scenario - dovrai usare la href=@Url.Action()sintassi dello stile.
Katstevens,

15

Non ricordo in quale versione di ASP.NET MVC (credo ASP.NET MVC 3+) / Rasoio è stata introdotta la dichiarazione di parametri parametrici o qualunque sia la funzione chiamata (parametro: x), ma per me questo è sicuramente il modo corretto di creare un collegamento con un ancoraggio in ASP.NET MVC.

@Html.ActionLink("Some link text", "MyAction", "MyController", protocol: null, hostName: null, fragment: "MyAnchor", routeValues: null, htmlAttributes: null)

Nemmeno l'argomento antipattern di Ed Blackburn da questa risposta può competere con quello.


1
Letteralmente questo mi ha salvato la vita. Attribuire il tuo post come la mia soluzione qui stackoverflow.com/questions/32420028/… .
Matteo,

11

L'ho fatto così:

<a href="@Url.Action("Index","Home")#features">Features</a>

1

Ecco l'esempio della vita reale

@Html.Grid(Model).Columns(columns =>
    {
           columns.Add()
                   .Encoded(false)
                   .Sanitized(false)
                   .SetWidth(10)
                   .Titled(string.Empty)
                   .RenderValueAs(x => @Html.ActionLink("Edit", "UserDetails", "Membership", null, null, "discount", new { @id = @x.Id }, new { @target = "_blank" }));

  }).WithPaging(200).EmptyText("There Are No Items To Display")

E la pagina di destinazione ha TAB

<ul id="myTab" class="nav nav-tabs" role="tablist">

        <li class="active"><a href="#discount" role="tab" data-toggle="tab">Discount</a></li>
    </ul>

0

La mia soluzione funzionerà se si applica ActionFilter al metodo di azione Sottocategoria, purché si desideri sempre reindirizzare l'utente allo stesso segnalibro:

http://spikehd.blogspot.com/2012/01/mvc3-redirect-action-to-html-bookmark.html

Modifica il buffer HTML e genera un piccolo javascript per indicare al browser di aggiungere il segnalibro.

Ovviamente potresti modificare il javascript per scorrere manualmente, invece di usare un segnalibro nell'URL!

Spero che sia d'aiuto :)


0

L'ho fatto e funziona per il reindirizzamento ad un'altra vista Penso che se aggiungi il #sectionLink dopo che funzionerà

<a class="btn yellow" href="/users/Create/@Model.Id" target="_blank">
                                        Add As User
                                    </a>
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.