将HTML放入Html.ActionLink(),再加上没有链接文本?


169

我有两个问题:

  1. 我想知道如何Html.ActionLink()在MVC视图中使用时不显示任何链接文本(实际上是Site.Master)。

没有一个不允许链接文本的重载版本,当我尝试仅传递一个blank时string,编译器告诉我它需要一个非空字符串。

我怎样才能解决这个问题?

  1. 我需要将<span>标签放入锚标签内,但无法使用Html.ActionLink();。我希望看到以下输出:

    跨度文字

如何将标签放在ASP.NET MVC的锚标签内?


拥有空白操作链接的目的/用途是什么?
大卫,

1
我将图像精灵用于导航栏,<li>您看到的是一个特定的导航按钮(在CSS样式表中指定了尺寸,背景pos等)。但是它必须链接到某些东西,所以我不想显示文本。我希望精灵为我做这件事。
MegaMatt

Answers:


322

您可以通过Url.Action呈现网址,而不是使用Html.ActionLink。

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

并做一个空白的网址,你可能有

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

3
我不得不使用<a href="@Url.Action("Index", "Home")"> <span>文本</ span> </a>,我的开发人员并没有问我为什么要做这对任何尝试使用以上答案并发现其无效的人可能会有所帮助。
Dave Haigh

2
@ Url.Action是在使用剃刀模板时。我已经更新了答案,因此您可以看到两者。
David

<a href=@Url.Action("Create", "Product")><span>Create</span></a>也可以。引号不是必需的。
大卫

1
对于静态内容,为什么不直接键入html?似乎不那么冗长和简单
-SkeetJon

如果要使用Ajax,则在Asp.Net Core 2中不再是真正的选择。
Zorkind '18年

17

自定义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();
}

14

如果您需要使用ajax或手动建立链接(使用标记)时无法使用的某些功能,则可以使用以下解决方法:

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

您可以使用任何文本代替“ LinkTextToken”,仅可以替换,重要的是不要在actionlink内的其他任何地方出现它。


6
+1好主意。在剃刀中,您必须在Html.Raw()
Carrie Kendall

谢谢:)现在,我明白了所用的东西,我几乎感到尴尬,在服务器上做这些事情真浪费了服务器资源...
Goran Obradovic 2014年

1
由于我使用的是@ Ajax.ActionLink,并且不想手动设置所有date-属性,因此这对我来说是最佳的解决方案。+1
asontu

谢谢,当我还使用Ajax.ActionLink时,它就像一个魅力。它似乎并没有降低任何速度,我必须保持相同的布局和样式。
Blacky Wolf

只是想说,这在.Net Core中不起作用,ToHtmlString()已在v2中删除,不确定v1
Zorkind 18'Aug

12

只需使用Url.Action代替Html.ActionLink

<li id="home_nav"><a href="<%= Url.Action("ActionName") %>"><span>Span text</span></a></li>

@CraigStunz为什么我们应该使用Url.Action而不是Html.ActionLink?
Roxy'Pro

6

这对我来说一直很好。它并不凌乱而且很干净。

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


Url.Action没有使用htmlAttributes的构造函数。与ActionLink不同。
barrypicker

2

我最终得到了一个自定义扩展方法。值得注意的是,当尝试将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>

1

我认为这在使用引导程序和某些glypicons时可能有用:

<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输出保持干净


1

这是@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);
        }
    }

1
受到启发并有能力做到这一点真是太好了。但是,我查看了嵌套的foreach语句并希望运行。它根本无法为大多数开发人员所维护。如果它是用石头黑盒子类型扩展方法设置的,那么可能还可以,但是它有代码气味。对于非常简单的东西,根本不容易看到。谢谢您的努力。
汤姆·斯蒂克2014年

我非常同意嵌套循环。为了简洁起见,它在那里。从优化立场来看嵌套的是for循环应该在自己的私人方法,并且参数需要被肯定,代码需要更多的防守,等等
威廉的孩子

0

非常简单

如果您想使用glyphicon图标,然后再添加“愿望清单”,

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

0

我的解决方案使用引导程序组件:

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

0

请尝试以下可能对您有帮助的代码。

 @Html.ActionLink(" SignIn", "Login", "Account", routeValues: null, htmlAttributes: new {  id = "loginLink" ,**@class="glyphicon glyphicon-log-in"** }) 

只需简单地添加,@ class然后实际的CSS类就可以帮助我解决我的问题
Ahsanul
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.