2008-10-17 28 views
47

En ASP.NET MVC, ¿hay un equivalente del ayudante Html.ActionLink para las etiquetas Img?Equivalente de imagen de ActionLink en ASP.NET MVC

Tengo una acción de controlador que genera un JPEG generado dinámicamente y quería usar las mismas expresiones Lambda para vincularme a él que HREF usando ActionLink.

Alternativamente, un ayudante que simplemente da la URL a una ruta (especificada nuevamente usando Lambdas) también sería aceptable.

EDIT: Originalmente había especificado que estaba usando la Vista previa 5, sin embargo, veo que se ha lanzado una versión Beta. Así que, en general, el número de versión era una información innecesaria, ya que puedo estar actualizando pronto :-)

Respuesta

20

Url.Action() obtendrá la URL vacía para la mayoría de las sobrecargas de Html.ActionLink, pero creo que la funcionalidad URL-from-lambda solo está disponible a través de Html.ActionLink hasta el momento. Con suerte, agregarán una sobrecarga similar a Url.Action en algún momento.

+0

tenía miedo de eso. –

+0

La funcionalidad parse-the-lambda es un buen método conveniente en MvcToolkit, es solo interno. Puede agregar su propio método de extensión que lo llame a través de la reflexión (o recompilar MvcToolkit con que se haga público), suponiendo que uno oficial lo reemplazará en breve. – stevemegson

+0

Si crea un buen método de extensión a partir de esto (algo así como: Html.ActionImage()), no debería saturar sus vistas :) –

4

En ASP.NET MVC Beta, se puede utilizar el método deHtml.BuildUrlFromExpression en el montaje de Futuros (que no está incluido en el valor por defecto ASP.NET MVC instalar, pero está disponible en CodePlex) para crear un enlace en torno una imagen - o cualquier HTML - utilizando la sintaxis de estilo ActionLink lambda, así:

<a href="<%=Html.BuildUrlFromExpression<MyController>(c => c.MyAction())%>"> 
    <%=Html.Image("~/Content/MyImage.gif")%> 
</a> 

para mantener su imagen Conexiones sin fronteras, necesitará añadir una regla CSS como esto:

img 
{ 
    border: none; 
} 
8

Utilicé un trabajo alrededor para colocar un marcador en lugar de texto para ActionLink y luego reemplazarlo con mi código de imagen. Algo como esto:

<%= Html.ActionLink("__IMAGE_PLACEHOLDER__", "Products").Replace("__IMAGE_PLACEHOLDER__", "<img src=\"" + myImgUrl + "\" />")%> 

No es la solución más elegante pero funciona.

+0

Esto es lo que estoy haciendo, excepto que tengo un método de extensión para compilar la etiqueta img . Sería genial resumir esto en un método de extensión en sí mismo, y podría hacerlo. –

39

Esta pregunta es más viejo, y sólo comenzó recientemente con ASP.NET MVC cuando el RC ya estaba fuera, pero para aquellos que encuentran esta cuestión más adelante como yo esto podría ser interesante:

Al menos en el RC puede utilizar Url.Action(), también con los tipos anónimos, el resultado es mucho mejor que las sugerencias anteriores, supongo:

<a href="<%= Url.RouteUrl("MyRoute", new { param1 = "bla", param2 = 5 }) %>"> 
    put in <span>whatever</span> you want, also <img src="a.gif" alt="images" />. 
</a> 

Hay muchas otras sobrecargas para RouteUrl así, por supuesto.

1

Es Url.Content() lo que estás buscando?

Dale algo así como Url.Content ("~/path/to/something.jpg") lo convertirá en la ruta adecuada en función de la raíz de la aplicación.

-Josh

47

Usted puede utilizar el método URL.Action

<a href="<%= Url.Action("Create") %>"><img src="../../Content/Images/add_48.png" /></a> 
+0

¡Esto funcionó muy bien!Acabo de pasar en la acción y el controlador y funcionó como un encanto! Gracias – daniellmb

+1

Esto todavía funciona bien en MVC3, usando la sintaxis Razor @ –

+0

@RichardEverett, entonces, ¿cómo usar Razor @? ¿te importaría proporcionar un código de demostración simple? –

2

Es bastante simple de lograr en MVC 2.He creado mi propio método de extensión muy simple para soportar expresiones Lambda para el ayudante Url.Action. Requiere que haga referencia a MVC 2 Futures.
Aquí está el código:

using System; 
using System.Linq.Expressions; 
using System.Web.Mvc; 
using System.Web.Routing; 

using ExpressionHelperInternal=Microsoft.Web.Mvc.Internal.ExpressionHelper; 

namespace Bnv.Bssi.Web.Infrastructure.Helpers 
{ 
    public static class UrlExtensions 
    { 
     public static string Action<TController>(this UrlHelper helper, Expression<Action<TController>> action) where TController : Controller 
     { 
      RouteValueDictionary routeValuesFromExpression = ExpressionHelperInternal.GetRouteValuesFromExpression<TController>(action); 

      return helper.Action(routeValuesFromExpression["action"].ToString(), routeValuesFromExpression); 
     } 
    } 
} 

Ésta es la forma en que lo utilice:

<img src="<%= Url.Action<YourController>(c => c.YourActionMethod(param1, param2)); %>" /> 
0

traté de poner la salida del Html.Image en mi Html.ImageLink ayudante.

@(new HtmlString(Html.ActionLink(Html.Image("image.gif").ToString(), "myAction", "MyController").ToString().Replace("&lt;", "<").Replace("&gt;", ">"))) 

El problema para mí es decir, que el nombre ActionLink está codificada por lo que tengo & LT en lugar de <.

Acabo de eliminar esta codificación y el resultado funciona para mí. (? ¿Hay una mejor manera de hacer esto en su lugar usando sustituir)

5

En MVC3, su enlace se vería así:

<a href="@Url.Action("Create")"><img src="../../Content/Images/add_48.png" /></a> 
+4

Y por supuesto, no olvide el atributo 'alt' para el elemento' img', si es posible. –

2

Yo sé que mi mensaje es demasiado tarde, pero quiero compartir :)

que añade el nuevo método de extensión algo como esto:

public static class ImageExtensions 
{ 
    public static MvcHtmlString ImageLink(this HtmlHelper htmlHelper, string imgSrc, string additionalText = null, string actionName = null, string controllerName = null, object routeValues = null, object linkHtmlAttributes = null, object imgHtmlAttributes = null) 
    { 
     var urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url; 
     var url = "#"; 
     if (!string.IsNullOrEmpty(actionName)) 
      url = urlHelper.Action(actionName, controllerName, routeValues); 

     var imglink = new TagBuilder("a"); 
     imglink.MergeAttribute("href", url); 
     imglink.InnerHtml = htmlHelper.Image(imgSrc, imgHtmlAttributes) + " " + additionalText; 
     linkHtmlAttributes = new RouteValueDictionary(linkHtmlAttributes); 
     imglink.MergeAttributes((IDictionary<string, object>)linkHtmlAttributes, true); 

     return MvcHtmlString.Create(imglink.ToString()); 
    } 

    public static MvcHtmlString Image(this HtmlHelper htmlHelper, string imgSrc, object imgHtmlAttributes = null) 
    { 
     var imgTag = new TagBuilder("img"); 
     imgTag.MergeAttribute("src", imgSrc); 
     if (imgHtmlAttributes != null) 
     { 
      imgHtmlAttributes = new RouteValueDictionary(imgHtmlAttributes); 
      imgTag.MergeAttributes((IDictionary<string, object>)imgHtmlAttributes, true); 
     } 
     return MvcHtmlString.Create(imgTag.ToString()); 
    } 
} 

Espero que esto ayudó.

1

Tomé las respuestas anteriores e hizo un poco de una extensión de la envoltura:

public static MvcHtmlString ActionImageLink(this HtmlHelper helper, string src, string altText, UrlHelper url, string actionName, string controllerName) 
     { 
      return ActionImageLink(helper, src, altText, url, actionName, controllerName, null, null); 
     } 

     public static MvcHtmlString ActionImageLink(this HtmlHelper helper, string src, string altText, UrlHelper url, string actionName, string controllerName, Dictionary<string, string> linkAttributes, Dictionary<string, string> imageAttributes) 
     { 
      return ActionImageLink(helper, src, altText, url, actionName, controllerName, null, linkAttributes, imageAttributes); 
     } 

     public static MvcHtmlString ActionImageLink(this HtmlHelper helper, string src, string altText, UrlHelper url, string actionName, string controllerName, dynamic routeValues, Dictionary<string, string> linkAttributes, Dictionary<string, string> imageAttributes) 
     { 
      var linkBuilder = new TagBuilder("a"); 
      linkBuilder.MergeAttribute("href", routeValues == null ? url.Action(actionName, controllerName) : url.Action(actionName, controllerName, routeValues)); 

      var imageBuilder = new TagBuilder("img"); 
      imageBuilder.MergeAttribute("src", url.Content(src)); 
      imageBuilder.MergeAttribute("alt", altText); 

      if (linkAttributes != null) 
      { 
       foreach (KeyValuePair<string, string> attribute in linkAttributes) 
       { 
        if (!string.IsNullOrWhiteSpace(attribute.Key) && !string.IsNullOrWhiteSpace(attribute.Value)) 
        { 
         linkBuilder.MergeAttribute(attribute.Key, attribute.Value); 
        } 
       } 
      } 

      if (imageAttributes != null) 
      { 
       foreach (KeyValuePair<string, string> attribute in imageAttributes) 
       { 
        if (!string.IsNullOrWhiteSpace(attribute.Key) && !string.IsNullOrWhiteSpace(attribute.Value)) 
        { 
         imageBuilder.MergeAttribute(attribute.Key, attribute.Value); 
        } 
       } 
      } 

      linkBuilder.InnerHtml = MvcHtmlString.Create(imageBuilder.ToString(TagRenderMode.SelfClosing)).ToString(); 
      return MvcHtmlString.Create(linkBuilder.ToString()); 
     } 

ha hecho más fácil para mí de todos modos, espero que ayude a otra persona.

+0

Me gusta esta extensión, sin embargo, el 'this HtmlHelper helper' es extraño. Lo cambié a 'este UrlHelper url' y lo llamo usando' Url.ActionImageLink (...) ' –

+0

O puede hacer algo como' var _url = new UrlHelper (htmlHelper.ViewContext.RequestContext) .Action (_actionName, _mergedRouteValues) ; 'obtener un UrlHelper. Descaradamente me robé esto del enlace @Tobi proporcionado. –

+0

@JimGilmartin Ya veo, buena idea. La única razón por la que puse el htmlhelper fue para poder usarlo de la misma manera que cualquier otra máquina de afeitar, lo que me ayuda a recordar dónde se almacena y se accede. – Jon

0

Agregando a los demás puestos: en mi caso (asp.net mvc 3) quería un enlace de imagen para que actúe como un selector de idiomas así que terminó con:

public static MvcHtmlString ImageLink(this HtmlHelper htmlHelper, string imgSrc, string cultureName, object htmlAttributes, object imgHtmlAttributes, string languageRouteName = "lang", bool strictSelected = false) 
     { 
      UrlHelper urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url; 
      TagBuilder imgTag = new TagBuilder("img"); 
      imgTag.MergeAttribute("src", imgSrc); 
      imgTag.MergeAttributes((IDictionary<string, string>)imgHtmlAttributes, true); 

      var language = htmlHelper.LanguageUrl(cultureName, languageRouteName, strictSelected);      
      string url = language.Url; 

      TagBuilder imglink = new TagBuilder("a"); 
      imglink.MergeAttribute("href", url); 
      imglink.InnerHtml = imgTag.ToString(); 
      imglink.MergeAttributes((IDictionary<string, string>)htmlAttributes, true); 

      //if the current page already contains the language parameter make sure the corresponding html element is marked 
      string currentLanguage = htmlHelper.ViewContext.RouteData.GetRequiredString("lang"); 
      if (cultureName.Equals(currentLanguage, StringComparison.InvariantCultureIgnoreCase)) 
      { 
       imglink.AddCssClass("selectedLanguage"); 
      } 
      return new MvcHtmlString(imglink.ToString()); 
     } 

El apoyo internalización se realiza a través de una ruta de idioma - fuente original here.

0

Buenas soluciones aquí, pero ¿y si quiere tener más que solo una imagen en el enlace de acción? Así es como lo hago:

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

El inconveniente es que todavía tengo que hacer un poco de estilo en el botón-elemento, pero se puede poner todo el HTML que desea en ese país.

Además, funciona con el ayudante del Ajax, así: https://stackoverflow.com/a/19302438/961139

Cuestiones relacionadas