Action Image MVC3 Razor

Quelle est la meilleure façon de remplacer les liens par des images en utilisant Razor dans MVC3. Je le fais simplement pour le moment:

<a href="@Url.Action("Edit", new { id=MyId })"><img src="../../Content/Images/Image.bmp", alt="Edit" /></a> 

y a-t-il un meilleur moyen?

118
demandé sur GEOCHET 2011-02-04 12:31:33

10 réponses

vous pouvez créer une méthode d'extension pour HtmlHelper pour simplifier le code dans votre fichier CSHTML. Vous pouvez remplacer vos étiquettes par une méthode comme celle-ci:

// Sample usage in CSHTML
@Html.ActionImage("Edit", new { id = MyId }, "~/Content/Images/Image.bmp", "Edit")

voici un exemple de méthode d'extension pour le code ci-dessus:

// Extension method
public static MvcHtmlString ActionImage(this HtmlHelper html, string action, object routeValues, string imagePath, string alt)
{
    var url = new UrlHelper(html.ViewContext.RequestContext);

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

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

    return MvcHtmlString.Create(anchorHtml);
}
216
répondu Lucas 2011-02-04 19:14:41

vous pouvez utiliser Url.Content qui fonctionne pour tous les liens comme il traduit le tilde ~ à l'uri racine.

<a href="@Url.Action("Edit", new { id=MyId })">
    <img src="@Url.Content("~/Content/Images/Image.bmp")", alt="Edit" />
</a>
63
répondu jgauffin 2014-09-15 05:22:04

S'appuyant sur la réponse de Lucas ci-dessus, il s'agit d'une surcharge qui prend un nom de contrôleur comme paramètre, similaire à ActionLink. Utilisez cette surcharge lorsque votre image est reliée à une Action dans un contrôleur différent.

// Extension method
public static MvcHtmlString ActionImage(this HtmlHelper html, string action, string controllerName, object routeValues, string imagePath, string alt)
{
    var url = new UrlHelper(html.ViewContext.RequestContext);

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

    // build the <a> tag
    var anchorBuilder = new TagBuilder("a");

    anchorBuilder.MergeAttribute("href", url.Action(action, controllerName, routeValues));
    anchorBuilder.InnerHtml = imgHtml; // include the <img> tag inside
    string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);

    return MvcHtmlString.Create(anchorHtml);
}
24
répondu Crake 2012-07-31 02:28:20

bien, vous pouvez utiliser la solution @Lucas, mais il y a aussi un autre moyen.

 @Html.ActionLink("Update", "Update", *Your object value*, new { @class = "imgLink"})

Maintenant, ajoutez cette classe sur un fichier CSS ou sur votre page:

.imgLink
{
  background: url(YourImage.png) no-repeat;
}

avec cette classe, tout lien aura l'image désirée.

11
répondu AdrianoRR 2011-06-27 16:46:19

cela s'est avéré être un fil très utile.

pour ceux qui sont allergiques aux bretelles bouclées, voici le VB.NET version des réponses de Lucas et Crake:

Public Module ActionImage
    <System.Runtime.CompilerServices.Extension()>
    Function ActionImage(html As HtmlHelper, Action As String, RouteValues As Object, ImagePath As String, AltText As String) As MvcHtmlString

        Dim url = New UrlHelper(html.ViewContext.RequestContext)

        Dim imgHtml As String
        'Build the <img> tag
        Dim imgBuilder = New TagBuilder("img")
        With imgBuilder
            .MergeAttribute("src", url.Content(ImagePath))
            .MergeAttribute("alt", AltText)
            imgHtml = .ToString(TagRenderMode.Normal)
        End With

        Dim aHtml As String
        'Build the <a> tag
        Dim aBuilder = New TagBuilder("a")
        With aBuilder
            .MergeAttribute("href", url.Action(Action, RouteValues))
            .InnerHtml = imgHtml 'Include the <img> tag inside
            aHtml = aBuilder.ToString(TagRenderMode.Normal)
        End With

        Return MvcHtmlString.Create(aHtml)

    End Function

    <Extension()>
    Function ActionImage(html As HtmlHelper, Action As String, Controller As String, RouteValues As Object, ImagePath As String, AltText As String) As MvcHtmlString

        Dim url = New UrlHelper(html.ViewContext.RequestContext)

        Dim imgHtml As String
        'Build the <img> tag
        Dim imgBuilder = New TagBuilder("img")
        With imgBuilder
            .MergeAttribute("src", url.Content(ImagePath))
            .MergeAttribute("alt", AltText)
            imgHtml = .ToString(TagRenderMode.Normal)
        End With

        Dim aHtml As String
        'Build the <a> tag
        Dim aBuilder = New TagBuilder("a")
        With aBuilder
            .MergeAttribute("href", url.Action(Action, Controller, RouteValues))
            .InnerHtml = imgHtml 'Include the <img> tag inside
            aHtml = aBuilder.ToString(TagRenderMode.Normal)
        End With

        Return MvcHtmlString.Create(aHtml)

    End Function

End Module
3
répondu dansan 2013-01-01 21:19:57

cette méthode d'extension fonctionne également (à placer dans une classe statique publique):

    public static MvcHtmlString 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 new MvcHtmlString( link.ToHtmlString().Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing)) );
    }
1
répondu Diego 2012-03-27 23:50:07

pour ajouter à tout le Travail impressionnant commencé par Luke je poste un de plus qui prend une valeur de classe css et traite classe et alt comme paramètres optionnels (valide sous ASP.NET 3.5+). Cela permettra plus de fonctionnalités mais réduira le nombre de méthodes surchargées nécessaires.

// Extension method
    public static MvcHtmlString ActionImage(this HtmlHelper html, string action,
        string controllerName, object routeValues, string imagePath, string alt = null, string cssClass = null)
    {
        var url = new UrlHelper(html.ViewContext.RequestContext);

        // build the <img> tag
        var imgBuilder = new TagBuilder("img");
        imgBuilder.MergeAttribute("src", url.Content(imagePath));
        if(alt != null)
            imgBuilder.MergeAttribute("alt", alt);
        if (cssClass != null)
            imgBuilder.MergeAttribute("class", cssClass);

        string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing);

        // build the <a> tag
        var anchorBuilder = new TagBuilder("a");

        anchorBuilder.MergeAttribute("href", url.Action(action, controllerName, routeValues));
        anchorBuilder.InnerHtml = imgHtml; // include the <img> tag inside
        string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);

        return MvcHtmlString.Create(anchorHtml);
    }
1
répondu Zack Jannsen 2013-01-24 03:53:05

modification de la diapositive aide changée

     public static IHtmlString ActionImageLink(this HtmlHelper html, string action, object routeValues, string styleClass, string alt)
    {
        var url = new UrlHelper(html.ViewContext.RequestContext);
        var anchorBuilder = new TagBuilder("a");
        anchorBuilder.MergeAttribute("href", url.Action(action, routeValues));
        anchorBuilder.AddCssClass(styleClass);
        string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);

        return new HtmlString(anchorHtml);
    }

classe CSS

.Edit {
       background: url('../images/edit.png') no-repeat right;
       display: inline-block;
       height: 16px;
       width: 16px;
      }

créer le lien juste passer le nom de classe

     @Html.ActionImageLink("Edit", new { id = item.ID }, "Edit" , "Edit") 
1
répondu dnxit 2013-03-06 22:02:08

j'ai rejoint la réponse de Lucas et " ASP.NET MVC Aides, la Fusion de deux objets htmlAttributes ensemble " et, plus controllerName de code suivant:

// Exemple d'utilisation dans CSHTML

 @Html.ActionImage("Edit",
       "EditController"
        new { id = MyId },
       "~/Content/Images/Image.bmp",
       new { width=108, height=129, alt="Edit" })

et la classe d'extension pour le code ci-dessus:

using System.Collections.Generic;
using System.Reflection;
using System.Web.Mvc;

namespace MVC.Extensions
{
    public static class MvcHtmlStringExt
    {
        // Extension method
        public static MvcHtmlString ActionImage(
          this HtmlHelper html,
          string action,
          string controllerName,
          object routeValues,
          string imagePath,
          object htmlAttributes)
        {
            ///q/action-image-mvc3-razor-61485/"img");
            imgBuilder.MergeAttribute("src", url.Content(imagePath));

            var dictAttributes = htmlAttributes.ToDictionary();

            if (dictAttributes != null)
            {
                foreach (var attribute in dictAttributes)
                {
                    imgBuilder.MergeAttribute(attribute.Key, attribute.Value.ToString(), true);
                }
            }                        

            string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing);

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

            return MvcHtmlString.Create(anchorHtml);
        }

        public static IDictionary<string, object> ToDictionary(this object data)
        {
            //https://stackoverflow.com/questions/6038255/asp-net-mvc-helpers-merging-two-object-htmlattributes-together

            if (data == null) return null; // Or throw an ArgumentNullException if you want

            BindingFlags publicAttributes = BindingFlags.Public | BindingFlags.Instance;
            Dictionary<string, object> dictionary = new Dictionary<string, object>();

            foreach (PropertyInfo property in
                     data.GetType().GetProperties(publicAttributes))
            {
                if (property.CanRead)
                {
                    dictionary.Add(property.Name, property.GetValue(data, null));
                }
            }
            return dictionary;
        }
    }
}
0
répondu qub1n 2017-05-23 12:17:25

Ce serait un travail très fin

<a href="<%:Url.Action("Edit","Account",new {  id=item.UserId }) %>"><img src="../../Content/ThemeNew/images/edit_notes_delete11.png" alt="Edit" width="25px" height="25px" /></a>
0
répondu user3181441 2014-01-10 11:03:30