Đưa HTML vào bên trong Html.ActionLink (), cộng với Không có văn bản liên kết?


169

Tôi có hai câu hỏi:

  1. Tôi tự hỏi làm thế nào tôi có thể hiển thị không có văn bản liên kết khi sử dụng Html.ActionLink()trong chế độ xem MVC (thực ra, đây là Site.Master).

Không có phiên bản quá tải không cho phép văn bản liên kết và khi tôi thử chuyển qua chỉ trong một khoảng trống string, trình biên dịch sẽ cho tôi biết nó cần một chuỗi không trống.

Làm thế nào tôi có thể sửa lỗi này?

  1. Tôi cần đặt <span>các thẻ trong thẻ neo, nhưng nó không hoạt động Html.ActionLink();. Tôi muốn xem kết quả sau:

    Khoảng cách văn bản

Làm cách nào tôi có thể đặt các thẻ bên trong thẻ neo trong ASP.NET MVC?


Mục đích / việc sử dụng để có một liên kết hành động trống là gì?
David

1
Tôi đang sử dụng một sprite hình ảnh cho một thanh điều hướng và <li>bạn đang thấy là một nút điều hướng cụ thể (với kích thước, vị trí nền, v.v. được chỉ định trong biểu định kiểu css). Nhưng nó phải liên kết với một cái gì đó, vì vậy tôi không muốn hiển thị văn bản. Tôi muốn sprite làm điều đó cho tôi.
MegaMatt

Câu trả lời:


322

Thay vì sử dụng Html.ActionLink, bạn có thể kết xuất một url thông qua Url.Action

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

Và để làm một url trống, bạn có thể có

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

3
Tôi đã phải sử dụng <a href="@Url.Action("Index", "Home")"> <span> Văn bản </ span> </a>, nhà phát triển của tôi không có mặt để hỏi tại sao tôi phải làm Điều này nhưng nó có thể hữu ích cho bất cứ ai cố gắng sử dụng câu trả lời ở trên và thấy nó không hoạt động.
Dave Haigh

2
@ Url.Action là khi sử dụng mẫu dao cạo. Tôi đã cập nhật câu trả lời để bạn có thể thấy cả hai.
David

<a href=@Url.Action("Create", "Product")><span>Create</span></a>cũng hoạt động. Các trích dẫn là không cần thiết.
David

1
Đối với nội dung tĩnh tại sao không gõ html trực tiếp? Có vẻ ít dài dòng và đơn giản hơn
SkeetJon

Không phải là một tùy chọn thực sự trong Asp.Net Core 2 nữa nếu bạn muốn sử dụng Ajax.
Zorkind

17

Một phần mở rộng HtmlHelper tùy chỉnh là một tùy chọn khác. Lưu ý : ParameterDixi là loại của riêng tôi. Bạn có thể thay thế một RouteValueDipedia nhưng bạn phải xây dựng nó theo cách khác.

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

Đây là cách giải quyết (thấp và bẩn) trong trường hợp bạn cần sử dụng ajax hoặc một số tính năng mà bạn không thể sử dụng khi tạo liên kết thủ công (sử dụng thẻ):

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

Bạn có thể sử dụng bất kỳ văn bản nào thay vì 'LinkTextToken', nó chỉ được thay thế, điều quan trọng là nó không xảy ra ở bất kỳ nơi nào khác trong liên kết hành động.


6
+1 Ý tưởng hay. Trong Dao cạo, bạn sẽ phải rap tất cả những thứ đó trongHtml.Raw()
Carrie Kendall

Cảm ơn :) Bây giờ tôi thấy những gì chúng tôi đã sử dụng, tôi gần như bối rối, làm những việc này trên máy chủ là lãng phí tài nguyên máy chủ như vậy ...
Goran Obradovic

1
Vì tôi đang sử dụng @ Ajax.ActionLink và không cảm thấy muốn cài đặt thủ công tất cả các date-thuộc tính, đây là giải pháp tốt nhất cho tôi. +1
asontu

Cảm ơn, đã làm việc như một cơ duyên khi tôi cũng đang sử dụng Ajax.ActionLink. Nó dường như không làm chậm bất cứ điều gì và tôi phải giữ nguyên bố cục và kiểu dáng.
Sói

Chỉ muốn nói rằng, điều này không hoạt động trong .Net Core, ToHtmlString () đã bị xóa trong v2 không chắc chắn về v1
Zorkind

12

Chỉ sử dụng Url.Actionthay vì Html.ActionLink:

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

@CraigStunz tại sao chúng ta nên sử dụng Url.Action thay vì Html.ActionLink?
Roxy'Pro

6

Điều này đã luôn làm việc tốt cho tôi. Nó không lộn xộn và rất sạch sẽ.

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


Url.Action không có hàm tạo sẽ lấy htmlAttribution. Không giống như ActionLink.
barrypicker

2

Tôi đã kết thúc với một phương pháp mở rộng tùy chỉnh. Đáng chú ý của nó, khi cố gắng đặt HTML bên trong một đối tượng Anchor, văn bản liên kết có thể ở bên trái hoặc bên phải của HTML bên trong. Vì lý do này, tôi đã chọn cung cấp các tham số cho HTML bên trong bên trái và bên phải - văn bản liên kết nằm ở giữa. Cả HTML bên trái và bên phải là tùy chọn.

Phương pháp mở rộng 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;
    }

Ví dụ về cách sử dụng:

Dưới đây là một ví dụ về việc sử dụng. Trong ví dụ này, tôi chỉ muốn html bên trong ở bên phải của văn bản liên kết ...

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

Các kết quả:

kết quả này trong HTML sau ...

<a href="/SomethingOtherThanHome/SomethingOtherThanIndex">Hello World<span class="caret" /></a>

1

Tôi nghĩ rằng điều này có thể hữu ích khi sử dụng bootstrap và một số 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>

Điều này sẽ hiển thị thẻ A, với một liên kết đến bộ điều khiển, với biểu tượng kẹp giấy đẹp trên đó để thể hiện một liên kết tải xuống và đầu ra html được giữ sạch sẽ


1

Đây là một bản mở rộng uber của câu trả lời của @ tvanfosson. Tôi đã được truyền cảm hứng từ nó và quyết định làm cho nó chung chung hơn.

    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
Thật tuyệt khi bạn được truyền cảm hứng và có khả năng làm điều này. Tuy nhiên, tôi nhìn vào các báo cáo foreach lồng nhau và muốn chạy. Nó chỉ đơn giản là nó không thể duy trì bởi hầu hết các nhà phát triển. Nếu nó được thiết lập khá đẹp trong phương thức mở rộng kiểu hộp đen thì có thể ok, nhưng nó có mùi mã. Không dễ dàng gì trong mắt đối với một cái gì đó khá đơn giản. Cảm ơn cho những nỗ lực của bạn mặc dù.
Tom Stickel

Tôi rất đồng ý về lồng cho vòng lặp. Vì lợi ích của sự cô đọng, nó ở đó. Từ quan điểm tối ưu hóa, vâng, vòng lặp lồng nhau phải ở trong phương thức riêng của nó và các tham số cần phải được xác nhận, mã cần phải phòng thủ hơn nhiều, v.v.
william-kid

0

Nó rất đơn giản.

Nếu bạn muốn có một cái gì đó như biểu tượng glyphicon và sau đó là "Danh sách mong muốn",

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

0

Giải pháp của tôi sử dụng các thành phần bootstrap:

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

0

Vui lòng thử bên dưới Mã có thể giúp bạn.

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

chỉ cần thêm đơn giản, lớp @ và sau đó lớp css thực tế giúp tôi giải quyết vấn đề của mình
Ahsanul
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.