Incluindo uma marca de âncora em um ASP.NET MVC Html.ActionLink

151

No ASP.NET MVC, estou tentando criar um link que inclua uma marca âncora (ou seja, direcionando o usuário para uma página e uma seção específica da página).

O URL que estou tentando criar deve ter a seguinte aparência:

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

Meu roteamento é configurado com o padrão:

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

A sintaxe do link de ação que estou 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>
<%} %>

Meu método de controlador é o seguinte:

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

   return View(itemList);
}

O texto acima corretamente retorna um URL da seguinte maneira:

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

Não consigo descobrir como adicionar a parte # section12 . A palavra "seção" é apenas a convenção que estou usando para dividir as seções da página, e o 12 é o ID da subcategoria, ou seja, child.ID.

Como posso fazer isso?

dp.
fonte

Respostas:

97

Eu provavelmente criaria o link manualmente, assim:

<a href="<%=Url.Action("Subcategory", "Category", new { categoryID = parent.ID }) %>#section12">link text</a>
LorenzCK
fonte
20
Deve realmente usar as sobrecargas do ActionLink, conforme descrito por @Brad Wilson.
mattruma
18
@mattruma desculpe, eu discordo. BEIJO. Por que ter um membro cheio de parâmetros, alguns dos quais são deixados como nulos, quando você pode simplesmente declará-lo explicitamente. Qualquer um pode ver o que significa acima, pelo qual a resposta de Brad é complicada e exige que você se dedique ao intelecto. Parâmetros demais é um anti-padrão reconhecido. C2.com/cgi/wiki?TooManyParameters
Ed Blackburn
2
Concordo. Ambos os métodos funcionam, mas como a maneira como os fragmentos são especificados nos URLs não será alterada no futuro próximo, acho que esse caminho é realmente mais legível e claro em sua intenção. Se necessário, você ainda pode estender o objeto Urlou Htmlcom um método personalizado, que inclui uma maneira simples de adicionar uma sequência de fragmentos.
31712 LorenzCK
282

Existem sobrecargas do ActionLink que usam um parâmetro de fragmento . Passando "section12" como seu fragmento, você terá o comportamento que procura.

Por exemplo, chamando o método LinkExtensions.ActionLink (HtmlHelper, String, String, String, String, String, String, Objeto, Objeto) :

<%= Html.ActionLink("Link Text", "Action", "Controller", null, null, "section12-the-anchor", new { categoryid = "blah"}, null) %>
Brad Wilson
fonte
1
Essas sobrecargas fazem parte de uma biblioteca de extensões? Parece que não os entendo.
Granada
Existem duas: string estática pública ActionLink (este HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, protocolo de string, string hostName, fragmento de string, objeto routeValues, objeto htmlAttributes); public static string ActionLink (this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, protocolo de string, string hostName, fragmento de string, RouteValueDictionary routeValues, IDictionary <string, objeto> htmlAttributes);
23909 Brad Wilson
11
Essa deve ser a resposta.
Rubens Mariuzzo
1
As sobrecargas do Html.ActionLink que permitem a especificação de uma âncora passando o fragmento obrigam você a passar o controlador pelo nome. Eu não gosto disso. Se o nome do controlador estiver incorreto, ocorrerão exceções em tempo de execução, em vez de erros de compilação.
R. Schreurs
1
@RobertMcKee se o texto do link for mais do que apenas texto, Html.ActionLink()não funcionaria em nenhum cenário - você precisaria usar a [email protected]()sintaxe do estilo.
#
15

Não me lembro em qual versão do ASP.NET MVC (ASP.NET MVC 3+ eu acredito) / Razor foi introduzida a declaração de parâmetrolabel ou como quer que seja chamada (parâmetro: x), mas, para mim, essa é definitivamente a maneira correta de crie um link com uma âncora no ASP.NET MVC.

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

Nem mesmo o argumento antipadrão de Ed Blackburns dessa resposta pode competir com isso.

O Gato de Botas
fonte
1
Literalmente, isso salvou minha vida. Atribuindo sua postagem como minha solução aqui stackoverflow.com/questions/32420028/… .
Mateus
11

Eu apenas fiz assim:

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

Aqui está o exemplo da vida real

@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 a página de destino tem TABS

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

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

Minha solução funcionará se você aplicar o ActionFilter ao método de ação Subcategoria, desde que você sempre deseje redirecionar o usuário para o mesmo marcador:

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

Ele modifica o buffer HTML e gera um pequeno pedaço de javascript para instruir o navegador a anexar o marcador.

Você pode modificar o javascript para rolar manualmente, em vez de usar um marcador na URL, é claro!

Espero que ajude :)

Spikeh
fonte
0

Eu fiz isso e funciona para redirecionar para outra visualização. Se você adicionar o #sectionLink depois, ele funcionará

<a class="btn yellow" href="/users/Create/@Model.Id" target="_blank">
                                        Add As User
                                    </a>
Ahmed Samir
fonte