Html.ActionLink()内にHTMLを配置し、さらにリンクテキストなし?


169

2つの質問があります。

  1. Html.ActionLink()MVCビューで使用しているときにリンクテキストを表示できないのではないかと思っています(実際、これはですSite.Master)。

リンクテキストを許可しないオーバーロードバージョンはありません。空白のみを渡そうとすると、空stringではない文字列が必要であるとコンパイラーから通知されます。

どうすれば修正できますか?

  1. <span>アンカータグ内にタグを配置する必要がありますが、では機能しませんHtml.ActionLink();。次の出力を確認したいのですが。

    スパンテキスト

ASP.NET MVCのアンカータグ内にタグを配置するにはどうすればよいですか?


空のアクションリンクを使用する目的/用途は何ですか?
デビッド

1
ナビゲーションバーに画像スプライトを使用してい<li>ますが、表示されているのは特定のナビゲーションボタンです(サイズ、背景位置などがcssスタイルシートで指定されています)。しかし、それは何かにリンクする必要があるので、テキストを表示したくありません。スプライトにそれをしてもらいたい。
メガマット2009

回答:


322

Html.ActionLinkを使用する代わりに、Url.Actionを介してURLをレンダリングできます

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

3
私は<a href="@Url.Action("Index", "Home")"> <span> Text </ span> </a>を使用する必要がありましたが、開発者はなぜ私がやらなければならないのか尋ねようとしませんでしたこれは、しかし、上記の答えを使用してそれがうまくいかなかったことを見つけることは誰にとっても役に立つかもしれません。
デイブヘイ2013

2
@ Url.Actionは、かみそりテンプレートを使用する場合です。両方を確認できるように、回答を更新しました。
デビッド

<a href=@Url.Action("Create", "Product")><span>Create</span></a>も動作します。引用符は必要ありません。
David

1
静的コンテンツの場合は、htmlを直接入力してみませんか?冗長ではなく、シンプルに見える
SkeetJon

Ajaxを使用する場合、Asp.Net Core 2の本当のオプションではなくなりました。
ゾーキンド

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いい考えです。Razorでは、そのすべてをラップする必要がありますHtml.Raw()
Carrie Kendall 14年

おかげで:)私たちが使用したものを見ると、私はほとんど恥ずかしくなり、サーバーでこれらのことをするのはサーバーリソースの浪費です...
Goran Obradovic

1
@ Ajax.ActionLinkを使用していてdate-、すべての属性を手動で設定する気がなかったので、これは私にとって最良のソリューションです。+1
asontu 2017年

ありがとう、私もAjax.ActionLinkを使用していたときは魅力のように働きました 何も遅くならないようで、同じレイアウトとスタイルを維持する必要がありました。
ブラッキーウルフ

言いたいことは、これは.Net Coreでは機能せず、ToHtmlString()はv2で削除され、v1については不明
Zorkind

12

Url.Action代わりに使用するだけですHtml.ActionLink

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

@CraigStunzなぜHtml.ActionLinkの代わりにUrl.Actionを使用する必要があるのですか?
Roxy'Pro

6

これは常に私にとってうまくいきました。汚くなく、とてもきれいです。

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


Url.Actionには、htmlAttributesを取るコンストラクターがありません。ActionLinkと同じではありません。
バリーピッカー

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

これは、ブートストラップといくつかのグリピコンを使用するときに役立つかもしれないと思いました:

<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ステートメントを見て実行したいと思います。それは単にほとんどの開発者が保守することはできません。それが石のブラックボックスタイプの拡張メソッドでかなり設定されている場合は、おそらく大丈夫ですが、コードの匂いがあります。かなり単純なものでは、目には簡単ではありません。しかしあなたの努力をありがとう。
Tom Stickel 14

ネストされたforループについては非常に同意します。簡潔にするためにあります。最適化の立場からはいforループを入れ子になったなど、より多くの防御的であることを、独自のプライベートメソッドであること、およびパラメータがアサートされる必要があり、コードのニーズなければならない
ウィリアム・キッド

0

とても簡単です。

グリフィコンアイコンや「ウィッシュリスト」などが必要な場合は、

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

単純にadd、@ class、次に実際のcssクラスで問題を解決できます
Ahsanul
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.