Включення тега прив’язки до 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 - ідентифікатор підкатегорії, тобто, дочірня ID.

Як я можу це зробити?

Відповіді:


97

Я б, мабуть, створив посилання вручну, як це:

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

20
Справді слід використовувати перевантаження для ActionLink, як описав @Brad Wilson.
mattruma

18
@mattruma вибачте, що я не згоден. KISS. Чому у вас є член, повний параметрів, деякі з яких залишені як нульові, коли ви можете просто чітко вказати його. Будь-хто може побачити, що вищезазначене означає, що відповідь Бреда суперечить і вимагає від вас зануритися в інтелігенцію. Занадто багато параметрів є визнаними антипаттерн .. 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, string linkText, string actionName, string stringName, строковий протокол, string hostName, фрагмент рядка, object objectValues, object htmlAttributes); загальнодоступний статичний рядок ActionLink (це HtmlHelper htmlHelper, string linkText, string actionName, string stringName, строковий протокол, string hostName, фрагмент рядка, RouteValueDictionary routeValues, IDictionary <string, object> htmlAttributes);
Бред Вілсон,

11
Це має бути відповіддю.
Рубенс Маріуццо

1
Перевантаження Html.ActionLink, які дозволяють конкретизувати якір, передаючи фрагмент, змушують передавати контролер на ім'я. Мені це не подобається. Якщо ім'я контролера невірно, будуть виникати винятки під час виконання, а не помилки компіляції.
Р. Шреурс

1
@RobertMcKee, якщо текст вашого посилання є не просто текстом, то він Html.ActionLink()би не працював ні в якому разі - вам потрібно використовувати href=@Url.Action()синтаксис стилів.
Катстевенс

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/… .
Матвій

11

Я просто зробив це так:

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

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

І на цільовій сторінці є 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>

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.