Image équivalente de ActionLink dans ASP.NET MVC
Dans ASP.NET MVC est-il un équivalent du Html.ActionLink helper pour les balises Img?
J'ai une action de contrôleur qui génère un JPEG généré dynamiquement et je voulais utiliser les mêmes expressions Lambda pour y lier comme je fais des HREFs en utilisant ActionLink.
Alternativement, un assistant qui donne simplement L'URL à une route (encore une fois spécifié en utilisant Lambdas) serait également acceptable.
EDIT : j'avais initialement spécifié que j'utilisais Preview 5, mais je vois qu'un Beta a été publié. Donc, dans l'ensemble, le numéro de version était un élément d'information inutile car je pourrais être en train de mettre à jour bientôt : -)
14 réponses
Url.Action() vous obtiendra L'URL nue pour la plupart des surcharges de Html.ActionLink, mais je pense que la fonctionnalité URL-from-lambda n'est disponible que via Html.ActionLink jusqu'à présent. Espérons qu'ils ajouteront une surcharge similaire à L'Url.Action à un certain point.
Vous pouvez utiliser L'URL.Méthode d'Action
<a href="<%= Url.Action("Create") %>"><img src="../../Content/Images/add_48.png" /></a>
Cette question est plus ancienne, et je viens de commencer récemment avec ASP.NET MVC quand le RC était déjà sorti, mais pour ceux qui trouvent cette question plus tard comme moi, cela pourrait être intéressant:
Au moins dans le RC, vous pouvez utiliser L'Url.Action() aussi avec les types anonymes, le résultat semble beaucoup plus agréable que les suggestions ci-dessus, je suppose:
<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>
Il y a aussi beaucoup d'autres surcharges pour RouteUrl, bien sûr.
J'ai utilisé une solution de contournement pour placer un marqueur au lieu du texte pour ActionLink, puis le remplacer par mon code d'image. Quelque chose comme ceci:
<%= Html.ActionLink("__IMAGE_PLACEHOLDER__", "Products").Replace("__IMAGE_PLACEHOLDER__", "<img src=\"" + myImgUrl + "\" />")%>
Pas la solution la plus élégante mais ça marche.
Dans MVC3, votre lien ressemblerait à ceci:
<a href="@Url.Action("Create")"><img src="../../Content/Images/add_48.png" /></a>
Dans ASP.NET MVC Beta, vous pouvez utiliser le Html.BuildUrlFromExpression méthode dans L'assembly Futures (qui n'est pas inclus dans la valeur par défaut ASP.NET MVC install, mais est disponible à partir de CodePlex ) pour créer un lien autour d'une image-ou de tout HTML-en utilisant la syntaxe ActionLink de style lambda, comme ceci:
<a href="<%=Html.BuildUrlFromExpression<MyController>(c => c.MyAction())%>">
<%=Html.Image("~/Content/MyImage.gif")%>
</a>
Pour garder vos liens d'image sans bordure, vous devrez ajouter une règle CSS comme ceci:
img
{
border: none;
}
Vous pouvez utiliser ceci control.It se comporte comme ActionLink.
Http://agilefutures.com/index.php/2009/06/actionimage-aspnet-mvc
C'est assez simple à réaliser dans MVC 2. J'ai créé ma propre méthode d'extension très simple pour prendre en charge les expressions Lambda pour L'Url.D'aide d'Action. Cela nécessite que vous référenciez Les contrats à terme MVC 2.
Voici le code:
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);
}
}
}
Voici comment vous l'utilisez:
<img src="<%= Url.Action<YourController>(c => c.YourActionMethod(param1, param2)); %>" />
Je sais que mon post est trop tard mais je veux partager:)
J'ai ajouté une nouvelle méthode d'extension quelque chose comme ceci:
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());
}
}
Espère que cela a aidé.
J'ai pris les réponses ci-dessus et fait un peu d'une extension wrapper:
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());
}
A rendu les choses plus faciles pour moi de toute façon, j'espère que cela aide quelqu'un d'autre.
J'ai essayé de mettre la sortie du Html.Image dans mon Html.ImageLink helper.
@(new HtmlString(Html.ActionLink(Html.Image("image.gif").ToString(), "myAction", "MyController").ToString().Replace("<", "<").Replace(">", ">")))
Le problème pour moi est que le nom ActionLink est encodé, donc j'ai < au lieu de <.>
Je viens de supprimer cet encodage et le résultat fonctionne pour moi. (Y a-t-il une meilleure façon de le faire à la place en utilisant replace?)
Ajout aux autres messages: dans mon cas (asp.net mvc 3) je voulais un lien d'image pour agir comme un sélecteur de langue donc je me suis retrouvé avec:
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());
}
Le support d'internalisation a été fait via une route linguistique-source originale ici .
Belles solutions ici, mais que faire si vous voulez avoir plus que juste une image dans le lien d'action? Voici comment je le fais:
@using (Html.BeginForm("Action", "Controler", ajaxOptions))
{
<button type="submit">
<img src="image.png" />
</button>
}
L'inconvénient est que je dois encore faire un peu de style sur l'élément button, mais vous pouvez y mettre tout le html que vous voulez.
Et cela fonctionne aussi avec L'Assistant Ajax: https://stackoverflow.com/a/19302438/961139