Помещение HTML в Html.ActionLink () плюс отсутствие текста ссылки?

У меня два вопроса:

  1. Мне интересно, как я могу не отображать текст ссылки при использовании Html.ActionLink() в представлении MVC (на самом деле это Site.Master).

Не существует перегруженной версии, в которой не разрешен текст ссылки, и когда я пытаюсь передать только пустой string, компилятор сообщает мне, что ему нужна непустая строка.

Как я могу это исправить?

  1. Мне нужно поместить теги <span> в тег привязки, но он не работает с Html.ActionLink();. Я бы хотел увидеть такой результат:

    Промежуточный текст

Как я могу поместить теги внутри тега привязки в ASP.NET MVC?


person MegaMatt    schedule 29.12.2009    source источник
comment
Для чего нужна пустая ссылка на действие?   -  person David    schedule 29.12.2009
comment
Я использую спрайт изображения для панели навигации, а <li>, который вы видите, - это конкретная кнопка навигации (с размером, позицией фона и т. Д., Указанными в таблице стилей css). Но он должен ссылаться на что-то, поэтому я не хочу отображать текст. Я хочу, чтобы это сделал за меня спрайт.   -  person MegaMatt    schedule 29.12.2009


Ответы (11)


Вместо использования Html.ActionLink вы можете отобразить URL-адрес через Url.Action

<a href="<%= Url.Action("Index", "Home") %>"><span>Text</span></a>
<a href="@Url.Action("Index", "Home")"><span>Text</span></a>

И чтобы сделать пустой URL-адрес, вы могли бы

<a href="<%= Url.Action("Index", "Home") %>"></a>
<a href="@Url.Action("Index", "Home")"></a>
person David    schedule 29.12.2009
comment
Мне пришлось использовать ‹a [email protected](Index, Home)› ‹span› Текст ‹/span› ‹/a›, моего разработчика нет рядом, чтобы спросить, зачем мне это нужно, но это может быть полезно для всех, кто пытается использовать приведенный выше ответ, и обнаружение, что это не сработало. - person Dave Haigh; 12.07.2013
comment
@ Url.Action - при использовании шаблона бритвы. Я обновил ответ, чтобы вы могли видеть оба. - person David; 12.07.2013
comment
<a [email protected]("Create", "Product")><span>Create</span></a> тоже работает. Цитаты не требуются. - person David; 15.09.2015
comment
Для статического контента почему бы не набрать html напрямую? Кажется менее многословным и простым - person SkeetJon; 02.12.2015
comment
Это больше не вариант в Asp.Net Core 2, если вы хотите использовать Ajax. - person Zorkind; 09.08.2018

Другой вариант - собственное расширение HtmlHelper. Примечание. ParameterDictionary - это мой собственный тип. Вы можете заменить RouteValueDictionary, но вам придется построить его по-другому.

public static string ActionLinkSpan( this HtmlHelper helper, string linkText, string actionName, string controllerName, object htmlAttributes )
{
    TagBuilder spanBuilder = new TagBuilder( "span" );
    spanBuilder.InnerHtml = linkText;

    return BuildNestedAnchor( spanBuilder.ToString(), string.Format( "/{0}/{1}", controllerName, actionName ), htmlAttributes );
}

private static string BuildNestedAnchor( string innerHtml, string url, object htmlAttributes )
{
    TagBuilder anchorBuilder = new TagBuilder( "a" );
    anchorBuilder.Attributes.Add( "href", url );
    anchorBuilder.MergeAttributes( new ParameterDictionary( htmlAttributes ) );
    anchorBuilder.InnerHtml = innerHtml;

    return anchorBuilder.ToString();
}
person tvanfosson    schedule 29.12.2009

Вот (низкий и грязный) обходной путь на случай, если вам нужно использовать ajax или какую-либо функцию, которую вы не можете использовать при создании ссылки вручную (с использованием тега):

<%= Html.ActionLink("LinkTextToken", "ActionName", "ControllerName").ToHtmlString().Replace("LinkTextToken", "Refresh <span class='large sprite refresh'></span>")%>

Вы можете использовать любой текст вместо LinkTextToken, он нужен только для замены, важно только, чтобы он нигде не встречался внутри actionlink.

person Goran Obradovic    schedule 06.06.2012
comment
+1 Хорошая идея. В Razor тебе придется все это читать за Html.Raw() - person Carrie Kendall; 10.06.2014
comment
Спасибо :) Теперь, когда я вижу, что мы использовали, я почти смущаюсь, делать эти вещи на сервере - такая трата ресурсов сервера ... - person Goran Obradovic; 10.06.2014
comment
Поскольку я использую @ Ajax.ActionLink и мне не хотелось вручную устанавливать все атрибуты date-, это лучшее решение для меня. +1 - person asontu; 15.03.2017
comment
Спасибо, работал отлично, когда я также использовал Ajax.ActionLink. Похоже, это ничего не замедляло, и мне пришлось сохранить тот же макет и стиль. - person Blacky Wolf; 23.03.2017
comment
Просто хочу сказать, что это не работает в .Net Core, ToHtmlString () был удален в v2, не уверен в v1 - person Zorkind; 09.08.2018

Просто используйте Url.Action вместо Html.ActionLink:

<li id="home_nav"><a href="<%= Url.Action("ActionName") %>"><span>Span text</span></a></li>
person Craig Stuntz    schedule 29.12.2009
comment
@CraigStunz, почему мы должны использовать Url.Action вместо Html.ActionLink? - person Roxy'Pro; 18.09.2017

У меня это всегда хорошо работало. Он не грязный и очень чистый.

<a href="@Url.Action("Index", "Home")"><span>Text</span></a>

person dbarth    schedule 07.04.2015
comment
Url.Action не имеет конструктора, который будет принимать атрибуты htmlAttributes. Не то же самое, что ActionLink. - person barrypicker; 10.08.2016

Я остановился на собственном методе расширения. Стоит отметить, что при попытке разместить HTML внутри объекта Anchor текст ссылки может быть либо слева, либо справа от внутреннего HTML. По этой причине я решил предоставить параметры для левого и правого внутреннего HTML - текст ссылки находится посередине. И левый, и правый внутренний HTML не являются обязательными.

Метод расширения ActionLinkInnerHtml:

    public static MvcHtmlString ActionLinkInnerHtml(this HtmlHelper helper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues = null, IDictionary<string, object> htmlAttributes = null, string leftInnerHtml = null, string rightInnerHtml = null)
    {
        // CONSTRUCT THE URL
        var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
        var url = urlHelper.Action(actionName: actionName, controllerName: controllerName, routeValues: routeValues);

        // CREATE AN ANCHOR TAG BUILDER
        var builder = new TagBuilder("a");
        builder.InnerHtml = string.Format("{0}{1}{2}", leftInnerHtml, linkText, rightInnerHtml);
        builder.MergeAttribute(key: "href", value: url);

        // ADD HTML ATTRIBUTES
        builder.MergeAttributes(htmlAttributes, replaceExisting: true);

        // BUILD THE STRING AND RETURN IT
        var mvcHtmlString = MvcHtmlString.Create(builder.ToString());
        return mvcHtmlString;
    }

Пример использования:

Вот пример использования. В этом примере мне нужен только внутренний html справа от текста ссылки ...

@Html.ActionLinkInnerHtml(
    linkText: "Hello World"
        , actionName: "SomethingOtherThanIndex"
        , controllerName: "SomethingOtherThanHome"
        , rightInnerHtml: "<span class=\"caret\" />"
        )

Результаты:

это приводит к следующему HTML ...

<a href="/SomethingOtherThanHome/SomethingOtherThanIndex">Hello World<span class="caret" /></a>
person barrypicker    schedule 10.08.2016

Я подумал, что это может быть полезно при использовании начальной загрузки и некоторых глипиконов:

<a class="btn btn-primary" 
    href="<%: Url.Action("Download File", "Download", 
    new { id = msg.Id, distributorId = msg.DistributorId }) %>">
    Download
    <span class="glyphicon glyphicon-paperclip"></span>
</a>

Это покажет тег A со ссылкой на контроллер, с красивым значком скрепки на нем, чтобы представить ссылку для загрузки, а вывод html останется чистым.

person Terry Kernan    schedule 18.04.2014

Вот убер-расширение ответа @tvanfosson. Меня это вдохновило, и я решил сделать его более общим.

    public static MvcHtmlString NestedActionLink(this HtmlHelper htmlHelper, string linkText, string actionName,
        string controllerName, object routeValues = null, object htmlAttributes = null,
        RouteValueDictionary childElements = null)
    {
        var htmlAttributesDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

        if (childElements != null)
        {
            var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);

            var anchorTag = new TagBuilder("a");
            anchorTag.MergeAttribute("href",
                routeValues == null
                    ? urlHelper.Action(actionName, controllerName)
                    : urlHelper.Action(actionName, controllerName, routeValues));
            anchorTag.MergeAttributes(htmlAttributesDictionary);
            TagBuilder childTag = null;

            if (childElements != null)
            {
                foreach (var childElement in childElements)
                {
                    childTag = new TagBuilder(childElement.Key.Split('|')[0]);
                    object elementAttributes;
                    childElements.TryGetValue(childElement.Key, out elementAttributes);

                    var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(elementAttributes);

                    foreach (var attribute in attributes)
                    {
                        switch (attribute.Key)
                        {
                            case "@class":
                                childTag.AddCssClass(attribute.Value.ToString());
                                break;
                            case "InnerText":
                                childTag.SetInnerText(attribute.Value.ToString());
                                break;
                            default:
                                childTag.MergeAttribute(attribute.Key, attribute.Value.ToString());
                                break;
                        }
                    }
                    childTag.ToString(TagRenderMode.SelfClosing);
                    if (childTag != null) anchorTag.InnerHtml += childTag.ToString();
                }                    
            }
            return MvcHtmlString.Create(anchorTag.ToString(TagRenderMode.Normal));
        }
        else
        {
            return htmlHelper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributesDictionary);
        }
    }
person william-kid    schedule 05.07.2014
comment
Здорово, что вы вдохновились и у вас есть возможность это сделать. Однако я смотрю на вложенные операторы foreach и хочу их запустить. Это просто не обслуживается большинством разработчиков. Если это довольно сложный метод расширения типа черного ящика, тогда, возможно, все в порядке, но у него есть запах кода. Совсем нелегко для глаз из-за чего-то довольно простого. Тем не менее, спасибо за ваши усилия. - person Tom Stickel; 13.09.2014
comment
Я полностью согласен с вложенными циклами for. Для краткости он есть. С точки зрения оптимизации да, вложенный цикл for должен быть в собственном закрытом методе, а параметры должны быть утверждены, код должен быть более защищенным и т. Д. - person william-kid; 16.10.2014

Все очень просто.

Если вы хотите иметь что-то вроде значка с глификоном, а затем «Список желаний»,

<span class="glyphicon-heart"></span> @Html.ActionLink("Wish List (0)", "Index", "Home")
person DanKodi    schedule 21.05.2014

Мое решение с использованием компонентов начальной загрузки:

<a class="btn btn-primary" href="@Url.Action("resetpassword", "Account")">
    <span class="glyphicon glyphicon-user"></span> Reset Password
</a>
person Carlos Toledo    schedule 26.08.2015

Пожалуйста, попробуйте следующий код, который может вам помочь.

 @Html.ActionLink(" SignIn", "Login", "Account", routeValues: null, htmlAttributes: new {  id = "loginLink" ,**@class="glyphicon glyphicon-log-in"** }) 
person Ahsanul    schedule 14.03.2015
comment
просто добавьте, @ class, а затем фактический класс css, помогите мне решить мою проблему - person Ahsanul; 15.03.2015