ASP.NET MVC Ajax.ActionLink mit Image

Antworten:

67

Von Stephen Walthe, von seinem Contact Manager-Projekt

 public static class ImageActionLinkHelper
{

    public static string ImageActionLink(this AjaxHelper helper, string imageUrl, string altText, string actionName, object routeValues, AjaxOptions ajaxOptions)
    {
        var builder = new TagBuilder("img");
        builder.MergeAttribute("src", imageUrl);
        builder.MergeAttribute("alt", altText);
        var link = helper.ActionLink("[replaceme]", actionName, routeValues, ajaxOptions);
        return link.Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing));
    }

}

Sie können jetzt Ihre Aspx-Datei eingeben:

<%= Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", new { id = item.Id }, new AjaxOptions { Confirm = "Delete contact?", HttpMethod = "Delete", UpdateTargetId = "divContactList" })%> 
Schwarzer Horus
quelle
2
Nur zu Ihrer Information, ich habe der ImageActionLink-Methode einen zusätzlichen Parameter hinzugefügt, um den Controller-Namen wie die MVC ActionLink-Methode zu akzeptieren, und er funktioniert einwandfrei! Vielen Dank
Dustin Laine
14
Darüber hinaus ist im obigen Codebeispiel-Link die Methode Ersetzen nicht als verfügbare Option verfügbar. Sie müssen zuerst ToString () oder ToHtmlString () aufrufen, bevor Sie Replace () aufrufen können.
Mwright
Ich fühle mich ein wenig albern, aber ich kann nicht herausfinden, wie ich das umsetzen soll. Ich nehme nicht an, dass Sie ein wenig erklären können, wohin die Klasse gehen muss?
Wil
1
@wil Dies ist eine Hilfsklasse (beachten Sie das Schlüsselwort this). Platzieren Sie es einfach an einer beliebigen Stelle und verweisen Sie über @using, und Sie sollten in der Lage sein, die neue Methode zu verwenden.
Asche999
1
Der Brauch Helfer ImageActionLink wird Text machen und nicht Markup bis zur Rückkehr ist aus der Zeichenfolge zu IHtmlString geändert
Rumi
35

Hier ist die einfachste Lösung, die ich gefunden habe:

<%= Ajax.ActionLink("[replacethis]", ...).Replace("[replacethis]", "<img src=\"/images/test.gif\" ... />" %>

Der Aufruf von Replace () wird verwendet, um das img- Tag in den Aktionslink zu verschieben. Sie müssen nur den Text "[Ersetzen]" (oder einen anderen sicheren Text) als temporären Platzhalter verwenden, um den Link zu erstellen.

Neal Stublen
quelle
1
Ich mag diese pragmatische Lösung!
Ropstah
Schöne und clevere Lösung. Vielen Dank.
Naveed Butt
4
Ich habe versucht, den obigen Code (mit .ToHtmlString () vor ".Replace") zu verwenden, aber er reicht nicht aus. Es wirft einfach die ganze Saite hinein. Hat sich das in mvc3 geändert oder fehlt mir etwas?
PedroC88
Darf ich auch vorschlagen, wie return new MvcHtmlString(link);für MVC3
Valamas
3
@ PedroC88 Sie können alles mit Html.Raw (...) verpacken und Razor wird es nicht codieren
Fernando Neira
32

Dies ist ein Razor / MVC 3-Update (und höher) für die Antwort von Black Horus:

using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;

public static class ImageActionLinkHelper
{
    public static IHtmlString ImageActionLink(this AjaxHelper helper, string imageUrl, string altText, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes = null)
    {
        var builder = new TagBuilder("img");
        builder.MergeAttribute("src", imageUrl);
        builder.MergeAttribute("alt", altText);
        builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
        var link = helper.ActionLink("[replaceme]", actionName, routeValues, ajaxOptions).ToHtmlString();
        return MvcHtmlString.Create(link.Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing)));
    }

}

Sie können jetzt Ihre .cshtml-Datei eingeben:

@Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", new { id = item.Id }, new AjaxOptions { Confirm = "Delete contact?", HttpMethod = "Delete", UpdateTargetId = "divContactList" })

31. Oktober 2013: Aktualisiert mit einem zusätzlichen Parameter, um zusätzliche HTML-Attribute für das Bildelement festzulegen. Verwendung:

@Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", new { id = item.Id }, new AjaxOptions { Confirm = "Delete contact?", HttpMethod = "Delete", UpdateTargetId = "divContactList" }, new{ style="border: none;" })
Arjan Einbu
quelle
Danke für das Update. Es war sehr hilfreich; Sie scheinen jedoch 2 zusätzliche Zeichen am Ende der .cshtml-Zeile zu haben.
Snumpy
Danke, @snumpy! Dies war ein typischer Fehler beim Kopieren und Einfügen ... :) Es wurde behoben
Arjan Einbu
Ich fühle mich ein wenig albern, aber ich kann nicht herausfinden, wie ich das umsetzen soll. Ich nehme nicht an, dass Sie ein wenig erklären können, wohin die Klasse gehen muss?
Wil
Sie können es überall platzieren. (Auf der Stammebene Ihrer MVC-Anwendung ist dies in Ordnung ...) (Möglicherweise müssen Sie oben in Ihren Rasiermesserdateien eine @ using-Direktive einfügen, die auf den Namespace der Klasse verweist, falls vorhanden.)
Arjan Einbu
Ich würde vorschlagen, dass Sie einen Attributparameter hinzufügen, um Attribut und Stil im gerenderten Bild festzulegen. (Zum Beispiel, um den Standardbildrand zu löschen). Ein nützliches Beispiel finden Sie unter diesem Link kitsula.com/Article/Html.ImageActionLink-extension
Ghini Antonio
6

Eine andere Lösung besteht darin, eine eigene Erweiterungsmethode zu erstellen:

ActionLink<TController>(this HtmlHelper helper, Expression<Action<TController>> action, string linkText, object htmlAttributes, LinkOptions options)

und als letzter Parameter ist die Aufzählung LinkOptions

[Flags]
public enum LinkOptions
{
    PlainContent = 0,
    EncodeContent = 1,
}

und dann können Sie es wie folgt verwenden:

Html.ActionLink<Car>(
     c => c.Delete(item.ID), "<span class=\"redC\">X</span>",
     new { Class = "none left" }, 
     LinkOptions.PlainContent)

Ich werde die vollständige Beschreibung dieser Lösung in meinem Blog veröffentlichen: http://fknet.wordpress.com/

frantisek
quelle
5

Die kurze Antwort lautet: Das ist nicht möglich. Sie können Ihre eigene Erweiterungsmethode schreiben, um einen ImageActionLink zu erhalten, was nicht allzu schwierig ist. Oder fügen Sie dem actionLink ein Attribut hinzu und ersetzen Sie die innere HTML durch das Image-Tag.

MrJavaGuy
quelle
5

Siehe Version 7 des Contact Manager-Tutorials unter http://asp.net/mvc . Stephen Walther hat ein Beispiel für die Erstellung eines Ajax.ActionLink, der ein Bild ist.


quelle
4

MVC3, Html.ActionImageLink und Ajax.ActionImageLink

Vielen Dank an alle anderen Antworten, die mir dabei geholfen haben.

public static MvcHtmlString ActionImageLink(this HtmlHelper helper, string imageUrl, string altText, string actionName, string controller, object routeValues)
{
    var builder = new TagBuilder("img");
    builder.MergeAttribute("src", imageUrl);
    builder.MergeAttribute("alt", altText);
    var link = helper.ActionLink("[replaceme]", actionName, controller, routeValues);
    return new MvcHtmlString(link.ToHtmlString().Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing)));
}
public static MvcHtmlString ActionImageLink(this AjaxHelper helper, string imageUrl, string altText, string actionName, string controller, object routeValues, AjaxOptions ajaxOptions)
{
    var builder = new TagBuilder("img");
    builder.MergeAttribute("src", imageUrl);
    builder.MergeAttribute("alt", altText);
    var link = helper.ActionLink("[replaceme]", actionName, controller, routeValues, ajaxOptions);
    return new MvcHtmlString(link.ToHtmlString().Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing)));
}
Valamas
quelle
Hinweis: Zum Kompilieren benötigen Sie Folgendes in Ihrem Code (VS 2010 kann fehlende Referenzen für Erweiterungsmethoden nicht auflösen): using System.Web.Mvc.Ajax; using System.Web.Mvc.Html;
Eric J.
4

Allgemeine Lösung: Fügen Sie einen beliebigen Rasierer in den Aktionslink ein

Es gibt eine viel bessere Lösung mit Razor-Vorlagendelegierten, mit der jeder Razor-Code auf ganz natürliche Weise in den Aktionslink eingefügt werden kann. Sie können also ein Bild oder einen anderen Code hinzufügen.

Dies ist die Erweiterungsmethode:

public static IHtmlString ActionLink<T>(this AjaxHelper ajaxHelper,
    T item, Func<T,HelperResult> template, string action,
    string controller, object routeValues, AjaxOptions options)
{
    string rawContent = template(item).ToHtmlString();
    MvcHtmlString a = ajaxHelper.ActionLink("$$$", action, 
        controller, routeValues, options);
    return MvcHtmlString.Create(a.ToString().Replace("$$$", rawContent));
}

Und so kann es verwendet werden:

@Ajax.ActionLink(car, 
    @<div>
        <h1>@car.Maker</h1>
        <p>@car.Description</p>
        <p>Price: @string.Format("{0:C}",car.Price)</p>
    </div>, ...

Auf diese Weise können Sie Razor mit Intellisense schreiben und jedes gewünschte Objekt für die Vorlage verwenden (das ViewModel oder ein anderes Objekt wie das Auto in meinem Beispiel). Sie können jeden Helfer in der Vorlage verwenden, um Bilder oder ein beliebiges Element zu verschachteln.

Hinweis für Resharper-Benutzer

Wenn Sie in Ihrem Projekt R # verwenden, können Sie R # -Anmerkungen hinzufügen , um Intellisense zu verbessern:

public static IHtmlString ActionLink<T>(this AjaxHelper ajaxHelper, T item,
    Func<T, HelperResult> template, 
    [AspMvcAction] string action, [AspMvcController] string controller, 
    object routeValues, AjaxOptions options)
JotaBe
quelle
Meiner Meinung nach ist dies die beste Lösung. Kompakt und markupfreundlich!
Mike Eshva
Der einzige Nachteil ist, dass R # es nicht versteht.
Mike Eshva
Wo kann ich diese Erweiterungsmethode platzieren?
Daniel Petrovaliev
Was meinst du mit "Wo kann ich diese Erweiterungsmethode platzieren?"? Ich verstehe nicht, was du meinst. Ist diese Antwort das, was Sie erwarten: Definieren Sie die Methode in einer beliebigen statischen Klasse und fügen Sie eine usingin Ihre Razor-Datei ein, um sie verwenden zu können?
JotaBe
1

Jede Antwort ist gut, aber ich fand die einfachste:

@Html.ActionLink( " ", "Index", "Countries", null, new
{
        style = "background: url('../../Content/Images/icon.png') no-repeat center right;display:block; height:24px; width:24px;margin-top:-2px;text-decoration:none;"
} )

Beachten Sie, dass für den Linktext ein Leerzeichen ("") verwendet wird. Es funktioniert nicht mit einem leeren Text.

Ali Adravi
quelle
0

Die erste Lösung besteht darin, eine statische Hilfsmethode DecodeLinkContent wie die folgende zu verwenden:

DecodeLinkContent(Html.ActionLink<Home>(c => c.Delete(item.ID), "<span class=\"redC\">X</span>",new { Class = "none left"})) 

DecodeLinkContent muss zuerst '>' und zuletzt '<' finden und den Inhalt durch HttpUtility.Decode (Inhalt) ersetzen.

Diese Lösung ist ein bisschen ein Hack, aber ich denke, es ist die einfachste.

frantisek
quelle
0

Das Update für MVC3 mit Templated Razor Delegates basiert auf T4Mvc , bringt aber so viel Leistung.

Basierend auf verschiedenen anderen Antworten auf dieser Seite.

        public static HelperResult WrapInActionLink(this AjaxHelper helper,ActionResult result, Func<object,HelperResult> template,AjaxOptions options)
    {
        var link=helper.ActionLink("[replaceme]",result,options);
        var asString=link.ToString();
        var replaced=asString.Replace("[replaceme]",template(null).ToString());

        return new HelperResult(writer =>
        {
            writer.Write(replaced);
        });
    }

Erlaubt:

@Ajax.WrapInActionLink(MVC.Deal.Details(deal.ID.Value),@<img alt='Edit deal details' src='@Links.Content.Images.edit_16_gif'/>, new AjaxOptions() { UpdateTargetId="indexDetails" })
Maslow
quelle
0

.li_inbox {Hintergrund: URL (inbox.png) no-repeat; Polsterung links: 40px; / image background wight 40px /}


<li class="li_inbox" >
          @Ajax.ActionLink("Inbox", "inbox","Home", new {  },
            new AjaxOptions
        {
            UpdateTargetId = "MainContent",
            InsertionMode = InsertionMode.Replace,
            HttpMethod = "GET"
          })

Samai
quelle
0

Versuche dies

@Html.Raw(HttpUtility.HtmlDecode(Ajax.ActionLink( "<img src=\"/images/sjt.jpg\" title=\"上一月\" border=\"0\" alt=\"上一月\" />", "CalendarPartial", new { strThisDate = Model.dtCurrentDate.AddMonths(-1).ToString("yyyy-MM-dd") }, new AjaxOptions { @UpdateTargetId = "calendar" }).ToString()))
Peter
quelle
Bitte bearbeiten Sie Ihre Antwort und formatieren Sie den Code, um ihn lesbar zu machen
Kleopatra
0

Schöne Lösungen hier, aber was ist, wenn Sie mehr als nur ein Bild im Actionlink haben möchten? So mache ich es:

     @using (Ajax.BeginForm("Action", "Controler", ajaxOptions))
     { 
        <button type="submit">
           <img src="image.png" />            
        </button>
     }

Der Nachteil ist, dass ich noch ein bisschen Styling für das Button-Element machen muss, aber Sie können dort alles HTML einfügen, was Sie wollen.

Jeroen Visscher
quelle
0

Alle sind sehr nette Lösungen, aber wenn Sie keine replacein Ihrer Lösung haben möchten, können Sie Folgendes versuchen:

{
    var url = new UrlHelper(helper.ViewContext.RequestContext);

    // build the <img> tag
    var imgBuilder = new TagBuilder("img");
    imgBuilder.MergeAttribute("src", url.Content(imageUrl));
    imgBuilder.MergeAttribute("alt", altText);
    string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing);

    //build the <a> tag
    var anchorBuilder = new TagBuilder("a");
    anchorBuilder.MergeAttribute("href", url.Action(actionName, controller, routeValues));
    anchorBuilder.InnerHtml = imgHtml; // include the <img> tag inside            
    anchorBuilder.MergeAttributes<string, object>(ajaxOptions.ToUnobtrusiveHtmlAttributes());
    string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);

    return MvcHtmlString.Create(anchorHtml);
}

Außerdem wird in meinem Fall url.Content(imageUrl)das Bild nicht angezeigt , wenn ich es nicht verwende .

Silvio
quelle
0

Ich habe festgestellt, dass die mit Abstand beste Lösung dafür darin besteht, das Eingabe-Tag mit type = "image" zu verwenden.

@using (Ajax.BeginForm( "LoadTest","Home" , new System.Web.Mvc.Ajax.AjaxOptions { UpdateTargetId = "[insert your target tag's id here]" }))
                {
                    <input type="image" class="[css style class here]" src="[insert image link here]">
                }

Es ist einfach und schnell.

Ich habe es in Kombination mit anderen Steuerelementbibliotheken verwendet, die AjaxOptions stören. Daher neige ich dazu, das gesamte System.Web.Mvc.Ajax.AjaxOptions auszutippen, falls ich in Zukunft einen anderen Satz ausprobieren sollte.

HINWEIS: Ich habe festgestellt, dass dies Probleme in MVC3 zu haben scheint (was mit type = "image" zu tun hat). Es funktioniert jedoch für MVC 4

James Pusateri
quelle
0

Verwenden Sie diese Erweiterung, um einen Ajax-Link mit glifyphicon zu generieren:

    /// <summary>
    /// Create an Ajax.ActionLink with an associated glyphicon
    /// </summary>
    /// <param name="ajaxHelper"></param>
    /// <param name="linkText"></param>
    /// <param name="actionName"></param>
    /// <param name="controllerName"></param>
    /// <param name="glyphicon"></param>
    /// <param name="ajaxOptions"></param>
    /// <param name="routeValues"></param>
    /// <param name="htmlAttributes"></param>
    /// <returns></returns>
    public static MvcHtmlString ImageActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string glyphicon, AjaxOptions ajaxOptions, RouteValueDictionary routeValues = null, object htmlAttributes = null)
    {
        //Example of result:          
        //<a id="btnShow" href="https://stackoverflow.com/Customers/ShowArtworks?customerId=1" data-ajax-update="#pnlArtworks" data-ajax-success="jsSuccess"
        //data-ajax-mode="replace" data-ajax-method="POST" data-ajax-failure="jsFailure" data-ajax-confirm="confirm" data-ajax-complete="jsComplete"
        //data-ajax-begin="jsBegin" data-ajax="true">
        //  <i class="glyphicon glyphicon-pencil"></i>
        //  <span>Edit</span>
        //</a>

        var builderI = new TagBuilder("i");
        builderI.MergeAttribute("class", "glyphicon " + glyphicon);
        string iTag = builderI.ToString(TagRenderMode.Normal);

        string spanTag = "";
        if (!string.IsNullOrEmpty(linkText))
        {
            var builderSpan = new TagBuilder("span") { InnerHtml = " " + linkText };
            spanTag = builderSpan.ToString(TagRenderMode.Normal);
        }

        //Create the "a" tag that wraps
        var builderA = new TagBuilder("a");

        var requestContext = HttpContext.Current.Request.RequestContext;
        var uh = new UrlHelper(requestContext);

        builderA.MergeAttribute("href", uh.Action(actionName, controllerName, routeValues));

        builderA.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        builderA.MergeAttributes((ajaxOptions).ToUnobtrusiveHtmlAttributes());

        builderA.InnerHtml = iTag + spanTag;

        return new MvcHtmlString(builderA.ToString(TagRenderMode.Normal));
    }
TotPeRo
quelle
0

Verwenden Sie HTML-Datenattribute

<a data-ajax="true" data-ajax-begin="..." data-ajax-success="..." href="@Url.Action("Delete")">
<i class="halflings-icon remove"></i>
</a>
              

Ersetze das

<i class="halflings-icon remove"></i>

mit deinem eigenen Bild

user1972111
quelle
0

Andere haben bei mir nicht funktioniert, da .ToHtmlString () in MVC 4 einen String ausgespuckt hat.

Im Folgenden wird eine ID an das Bearbeitungssteuerelement übergeben und anstelle des Textspags ein Bearbeitungsbild angezeigt:

@MvcHtmlString.Create(Ajax.ActionLink("Spag", "Edit", new { id = item.x0101EmployeeID }, new AjaxOptions() { UpdateTargetId = "selectDiv", InsertionMode = InsertionMode.Replace, HttpMethod = "GET" }).ToHtmlString().Replace("Spag", "<img src=\"" + Url.Content("../../Images/edit.png") + "\" />"))
Jplum
quelle
-1
actionName+"/"+routeValues Proje/ControlName/ActionName/Id




    using System.Web;
    using System.Web.Mvc;
    using System.Web.Mvc.Ajax;

    namespace MithatCanMvc.AjaxHelpers
{

    public static class ImageActionLinkHelper
    {
        public static IHtmlString ImageActionLink(this AjaxHelper helper, string imageUrl, string altText, string actionName, string routeValues, AjaxOptions ajaxOptions)
        {
            var builder = new TagBuilder("img");
            builder.MergeAttribute("src", imageUrl);
            builder.MergeAttribute("alt", altText);
            var link = helper.ActionLink("[replaceme]", actionName+"/"+routeValues, ajaxOptions).ToHtmlString();
            return MvcHtmlString.Create(link.Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing)));

        }

    }

}
Mithat CAN
quelle
-2

Ich weiß nicht, das scheint mir einfacher zu sein:

    <a href="@Url.Action("index", "home")">
        <img src="~/Images/rocket.png" width="25" height="25" title="Launcher" />
    </a>
John Coder
quelle
Keine Antwort auf die Frage
Derrick