Gambar Aksi MVC3 Razor

119

Apa cara terbaik untuk mengganti tautan dengan gambar menggunakan Razor di MVC3. Saya hanya melakukan ini saat ini:

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

Apakah ada cara yang lebih baik?

davy
sumber
15
Tidak terkait langsung, tetapi saya sangat menyarankan Anda menggunakan file PNG atau JPG (tergantung pada konten gambar) daripada file BMP. Dan seperti yang disarankan @jgauffin, coba juga gunakan application relative paths ( ~/Content). Jalur ../../Contentmungkin tidak valid dari rute yang berbeda (mis /. /Home, /Home/Index).
Lucas
Terima kasih Lucas. Saya memang menggunakan png tetapi saran untuk menggunakan URL. Konten adalah apa yang saya cari. voting :)
davy

Jawaban:

217

Anda dapat membuat metode ekstensi untuk HtmlHelper untuk menyederhanakan kode dalam file CSHTML Anda. Anda dapat mengganti tag Anda dengan metode seperti ini:

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

Berikut ini contoh metode ekstensi untuk kode di atas:

// 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);
}
Lucas
sumber
5
Potongan yang bagus. Siapa pun yang ingin menggunakan ini dengan T4MVC hanya perlu mengubah jenis routeValuesmenjadi ActionResultdan kemudian url.Actionfungsi berubah routeValuesmenjadirouteValues.GetRouteValueDictionary()
JConstantine
12
@Kasper Skov: Tempatkan metode dalam kelas statis, lalu referensikan namespace kelas tersebut di Web.config di /configuration/system.web/pages/namespaceselemen tersebut.
Umar Farooq Khawaja
4
Bagus !, alih-alih alt, saya menerima objek untuk menerima properti html menggunakan objek anonim kemudian var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);dan akhirnyaforeach (var attr in attributes){ imgBuilder.MergeAttribute(attr.Key, attr.Value.ToString());}
guzart
7
Saya tidak bisa mendapatkan ini berfungsi sampai saya menyadari bahwa karena saya menggunakan Area, referensi ke namespace kelas (seperti yang ditunjukkan oleh Umar) perlu ditambahkan ke SEMUA file web.config di folder Tampilan untuk semua Area serta /Viewsfolder tingkat atas
Mark_Gibson
2
Jika Anda hanya membutuhkan ini dalam satu halaman, daripada mengubah file Web.config, Anda dapat menambahkan pernyataan @using di .cshtml dan merujuk namespace
JML
64

Anda dapat menggunakan Url.Contentyang berfungsi untuk semua tautan karena itu menerjemahkan tilde ~ke uri root.

<a href="@Url.Action("Edit", new { id=MyId })">
    <img src="@Url.Content("~/Content/Images/Image.bmp")", alt="Edit" />
</a>
jgauffin.dll
sumber
3
Ini bekerja dengan baik di MVC3. Terima kasih! <a href="@Url.Action("Index","Home")"><img src="@Url.Content("~/Content/images/myimage.gif")" alt="Home" /></a>
rk1962
24

Berdasarkan jawaban Lucas di atas, ini adalah kelebihan beban yang menggunakan nama pengontrol sebagai parameter, mirip dengan ActionLink. Gunakan kelebihan beban ini saat gambar Anda ditautkan ke Tindakan di pengontrol yang berbeda.

// 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);
}
Berbunyi nyaring
sumber
1
tidak ada komentar pada Anda menambahkan di sini ... baik saya katakan modifikasi yang bagus untuk kode yang diberikan. +1 dari saya.
Zack Jannsen
11

Nah, Anda bisa menggunakan solusi @Lucas, tetapi ada juga cara lain.

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

Sekarang, tambahkan kelas ini pada file CSS atau di halaman Anda:

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

Dengan kelas itu, tautan apa pun akan memiliki gambar yang Anda inginkan.

AdrianoRR
sumber
2
@Kaspora Saya lupa masalah kecil ini. Untuk beberapa alasan, bantuan penggantian khusus actionLink ini, tidak berfungsi dengan contoh di atas. Anda harus melakukan ControllerNametindakan Anda. Seperti ini:@Html.ActionLink("Update", "Update", "*Your Controller*",*object values*, new {@class = "imgLink"})
AdrianoRR
3

Ini ternyata utas yang sangat berguna.

Bagi mereka yang alergi terhadap kawat gigi keriting, berikut adalah jawaban Lucas dan Crake versi VB.NET:

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
dansan
sumber
1

Metode ekstensi ini juga berfungsi (untuk ditempatkan di kelas statis publik):

    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)) );
    }
Diego
sumber
1

Untuk menambah semua pekerjaan Mengagumkan yang dimulai oleh Luke, saya memposting satu lagi yang mengambil nilai kelas css dan memperlakukan kelas dan alt sebagai parameter opsional (valid di bawah ASP.NET 3.5+). Ini akan memungkinkan lebih banyak fungsionalitas tetapi mengurangi jumlah metode kelebihan beban yang diperlukan.

// 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);
    }
Zack Jannsen
sumber
Selain itu, bagi siapa pun yang baru mengenal MVC, petunjuk bermanfaat - nilai routeValue harus @ RouteTable.Routes ["Home"] atau apa pun id "route" Anda ada di RouteTable.
Zack Jannsen
1

modifikasi slide mengubah Helper

     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);
    }

Kelas CSS

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

Buat tautan, cukup berikan nama kelas

     @Html.ActionImageLink("Edit", new { id = item.ID }, "Edit" , "Edit") 
dnxit
sumber
0

Saya telah bergabung dengan jawaban dari Lucas dan " ASP.NET MVC Helpers, Menggabungkan dua objek htmlAttributes bersama-sama " dan ditambah controllerName ke kode berikut:

// Contoh penggunaan dalam CSHTML

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

Dan kelas ekstensi untuk kode di atas:

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)
        {
            ///programming/4896439/action-image-mvc3-razor
            var url = new UrlHelper(html.ViewContext.RequestContext);

            // build the <img> tag
            var imgBuilder = new TagBuilder("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)
        {
            ///programming/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;
        }
    }
}
Tomas Kubes
sumber
0

Ini akan bekerja dengan sangat baik

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