Включение тега привязки в ASP.NET MVC Html.ActionLink


151

В ASP.NET MVC я пытаюсь создать ссылку, которая включает в себя тег привязки (то есть направляет пользователя на страницу и в определенный раздел страницы).

URL, который я пытаюсь создать, должен выглядеть следующим образом:

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

Моя маршрутизация настроена со стандартом:

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

Синтаксис ссылки действия, который я использую:

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

Мой метод контроллера заключается в следующем:

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

   return View(itemList);
}

Выше правильно возвращает URL следующим образом:

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

Я не могу понять, как добавить часть # section12 . Слово «раздел» - это просто соглашение, которое я использую для разбиения разделов страницы, а 12 - это идентификатор подкатегории, то есть child.ID.

Как я могу это сделать?

Ответы:


97

Я бы, наверное, построил ссылку вручную, вот так:

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

20
Следует действительно использовать перегрузки для ActionLink, как описано @Brad Wilson.
— Матрума

18
@mattruma извините, я не согласен. ПОЦЕЛУЙ. Зачем иметь элемент, полный параметров, некоторые из которых остаются нулевыми, если вы можете просто указать это явно. Любой может увидеть, что означает вышесказанное, когда ответ Брэда запутан и требует от вас углубления в интеллигентность. Слишком много параметров является признанным анти-паттерном. C2.com/cgi/wiki?TooManyParameters
— Ed Blackburn

2
Я согласен. Оба метода работают, но так как способ указания фрагментов в URL-адресах не изменится в ближайшем будущем, я думаю, что этот способ на самом деле более читабелен и понятен в своем намерении. При необходимости вы все равно можете расширить объект Urlили Htmlс помощью специального метода, который включает простой способ добавления строки фрагмента.
— LorenzCK

282

Существуют перегрузки ActionLink, которые принимают параметр фрагмента . Передача "section12" в качестве вашего фрагмента даст вам поведение, которое вы ищете.

Например, вызов метода 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
Являются ли эти перегрузки частью библиотеки расширений? Я, кажется, не понимаю их.
— граната

Их две: общедоступная статическая строка ActionLink (это HtmlHelper htmlHelper, строка linkText, строка actionName, строка controllerName, строковый протокол, строка hostName, фрагмент строки, объект routeValues, объект htmlAttributes); открытая статическая строка ActionLink (this HtmlHelper htmlHelper, строка linkText, строка actionName, строка controllerName, строковый протокол, строка hostName, фрагмент строки, RouteValueDictionary routeValues, IDictionary <строка, объект> htmlAttributes);
— Брэд Уилсон

11
Это должно быть ответом.
— Рубенс Мариуццо

1
Перегрузки Html.ActionLink, которые позволяют указать привязку при передаче фрагмента, вынуждают вас передавать контроллер по имени. Мне это не нравится Если имя контроллера неверно, возникнут исключения времени выполнения, а не ошибки компиляции.
— Р. Шреурс

1
@RobertMcKee, если текст вашей ссылки - это больше, чем просто текст, он Html.ActionLink()не будет работать ни в одном сценарии - вам нужно будет использовать href=@Url.Action()синтаксис стиля.
— Katstevens

15

Я не помню, в какой версии ASP.NET MVC (я полагаю, ASP.NET MVC 3+) / Razor была добавлена ​​функция метки параметра или как она называется (параметр: x), но для меня это определенно правильный способ построить ссылку с якорем в ASP.NET MVC.

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

Даже аргумент антипаттерна Эд Блэкбернса из этого ответа не может сравниться с этим.


1
Буквально это спасло мне жизнь. Приписать ваш пост в качестве моего решения здесь stackoverflow.com/questions/32420028/… .
— Мэтью


1

Вот пример из реальной жизни

@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")

И на целевой странице есть вкладки

<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

Мое решение будет работать, если вы примените ActionFilter к методу действия «Подкатегория», если вы всегда хотите перенаправить пользователя к одной и той же закладке:

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

Он изменяет HTML-буфер и выводит небольшой фрагмент JavaScript, чтобы дать браузеру команду добавить закладку.

Вы можете изменить javascript для ручной прокрутки, вместо использования закладки в URL, конечно!

Надеюсь, поможет :)


0

Я сделал это, и он работает для перенаправления в другое представление, я думаю, если вы добавите #sectionLink после того, как он будет работать

<a class="btn yellow" href="/users/Create/@Model.Id" target="_blank">
                                        Add As User
                                    </a>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.