Включение тега привязки в 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.