img - Action Image MVC3 Navaja
render byte array as image in asp net mvc (10)
¿Cuál es la mejor manera de reemplazar enlaces con imágenes usando Razor en MVC3? Simplemente hago esto en este momento:
<a href="@Url.Action("Edit", new { id=MyId })"><img src="../../Content/Images/Image.bmp", alt="Edit" /></a>
¿Hay una mejor manera?
Bueno, podrías usar la solución @Lucas, pero también hay otra manera.
@Html.ActionLink("Update", "Update", *Your object value*, new { @class = "imgLink"})
Ahora, agregue esta clase en un archivo CSS o en su página:
.imgLink
{
background: url(YourImage.png) no-repeat;
}
Con esa clase, cualquier enlace tendrá su imagen deseada.
Este método de extensión también funciona (para ser colocado en una clase pública estática):
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)) );
}
Esto resultó ser un hilo muy útil.
Para aquellos que son alérgicos a las llaves, aquí está la versión VB.NET de las respuestas de Lucas y 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
Esto sería trabajo muy bien
<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>
Me he unido a la respuesta de Lucas y " ASP.NET MVC Helpers, fusionando dos objetos htmlAttributes juntos " y más controllerName al siguiente código:
// Uso de muestra en CSHTML
@Html.ActionImage("Edit",
"EditController"
new { id = MyId },
"~/Content/Images/Image.bmp",
new { width=108, height=129, alt="Edit" })
Y la clase de extensión para el código de arriba:
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)
{
//https://.com/questions/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)
{
//https://.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;
}
}
}
Para agregar a todo el increíble trabajo iniciado por Luke, estoy publicando uno más que toma un valor de clase css y trata a clase y alt como parámetros opcionales (válido en ASP.NET 3.5+). Esto permitirá una mayor funcionalidad pero reducirá el número de métodos sobrecargados necesarios.
// 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);
}
Puede crear un método de extensión para HtmlHelper para simplificar el código en su archivo CSHTML. Puede reemplazar sus etiquetas con un método como este:
// Sample usage in CSHTML
@Html.ActionImage("Edit", new { id = MyId }, "~/Content/Images/Image.bmp", "Edit")
Aquí hay un método de muestra de extensión para el código anterior:
// 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);
}
Puede usar Url.Content
que funciona para todos los enlaces a medida que traduce la tilde ~
al uri raíz.
<a href="@Url.Action("Edit", new { id=MyId })">
<img src="@Url.Content("~/Content/Images/Image.bmp")", alt="Edit" />
</a>
Sobre la base de la respuesta de Lucas anterior, esta es una sobrecarga que toma un nombre de controlador como parámetro, similar a ActionLink. Use esta sobrecarga cuando su imagen se vincule a una Acción en un controlador diferente.
// 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);
}
la modificación de diapositiva cambió 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);
}
Clase de CSS
.Edit {
background: url(''../images/edit.png'') no-repeat right;
display: inline-block;
height: 16px;
width: 16px;
}
Crea el enlace solo pasa el nombre de la clase
@Html.ActionImageLink("Edit", new { id = item.ID }, "Edit" , "Edit")