2008-10-17 10 views
47

Dans ASP.NET MVC, existe-t-il un équivalent de l'aide Html.ActionLink pour les balises Img?Image équivalente à ActionLink dans ASP.NET MVC

J'ai une action du contrôleur qui génère un fichier JPEG généré dynamiquement et je voulais utiliser les mêmes expressions Lambda pour créer un lien avec moi que pour les HREF utilisant ActionLink. Alternativement, une aide qui donne juste l'URL à un itinéraire (encore spécifié en utilisant Lambda) serait également acceptable.

EDIT: J'avais initialement spécifié que j'utilisais Preview 5, mais je vois qu'une bêta a été publiée. Donc tout dans tout le numéro de version était un élément d'information inutile car je vais peut-être mettre à jour bientôt :-)

Répondre

20

Url.Action() vous obtiendrez l'URL nue pour la plupart des surcharges de Html.ActionLink, mais je pense que la fonctionnalité URL-from-lambda est uniquement disponible via Html.ActionLink jusqu'à présent. Espérons qu'ils vont ajouter une surcharge similaire à Url.Action à un moment donné.

+0

J'avais peur de cela. –

+0

La fonctionnalité parse-the-lambda est une bonne méthode pratique dans MvcToolkit, elle est juste interne. Vous pouvez ajouter votre propre méthode d'extension qui l'appelle par réflexion (ou recompiler MvcToolkit avec ce rendu public), en supposant que celle-ci sera remplacée sous peu. – stevemegson

+0

Si vous faites une belle extension extension de ceci (quelque chose comme: Html.ActionImage()), il ne devrait pas encombrer vos vues :) –

4

Dans ASP.NET MVC Beta, vous pouvez utiliser la méthode de Html.BuildUrlFromExpression dans l'assemblage à terme (qui ne sont pas inclus dans la valeur par défaut ASP.NET MVC installer, mais il est disponible à partir CodePlex) pour créer un lien vers une image - ou tout HTML - en utilisant la syntaxe ActionLink style lambda, comme ceci:

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

pour garder votre image liens sans frontières, vous aurez besoin d'ajouter une règle CSS comme ceci:

img 
{ 
    border: none; 
} 
8

J'ai utilisé un travail autour de placer un marqueur au lieu de 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 cela fonctionne.

+0

C'est ce que je fais, sauf que j'ai une méthode d'extension pour construire la balise img . Ce serait génial d'en finir avec une méthode d'extension, et je pourrais le faire. –

39

Cette question est plus ancienne, et je viens récemment commencé avec ASP.NET MVC lorsque le RC était déjà, mais pour ceux qui trouvent cette question plus tard comme moi cela pourrait être intéressant:

au moins dans la RC vous pouvez utiliser Url.Action() également avec des types anonymes, le résultat est bien plus beau 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 beaucoup d'autres pour RouteUrl que les surcharges ainsi, bien sûr.

1

Est-Url.Content() ce que vous cherchez? Donnez-lui quelque chose comme Url.Content ("~/path/to/something.jpg") il le transformera en le chemin approprié basé sur la racine de l'application.

-Josh

47

Vous pouvez utiliser la méthode URL.Action

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

Cela a bien fonctionné!Juste passé dans l'action et le contrôleur et cela a fonctionné comme un charme! Merci – daniellmb

+1

Cela fonctionne toujours bien dans MVC3, en utilisant la syntaxe Razor @ –

+0

@RichardEverett alors comment utiliser le Razor @? Pourriez-vous fournir un code de démonstration simple? –

2

Il 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'aide Url.Action. Cela nécessite que vous référenciez MVC 2 Futures.
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 l'utiliser:

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

J'ai essayé de mettre la sortie du Html.Image dans mon aide Html.ImageLink.

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

Le problème pour moi est que le nom ActionLink est codé si je & lt au lieu de <.

Je viens de supprimer cet encodage et le résultat fonctionne pour moi. (? Y at-il une meilleure façon de le faire au lieu d'utiliser le remplacer)

5

En MVC3, votre lien ressemblerait à ceci:

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

Et bien sûr, ne pas oublier l'attribut' alt' pour l'élément 'img', si possible. –

2

Je sais que mon poste est trop tard, mais je veux :) part

J'ajouté quelque chose comme nouvelle méthode d'extension 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()); 
    } 
} 

Hope this aidé.

1

Je pris les réponses ci-dessus et fait un peu d'une extension d'emballage:

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 plus facile pour moi de toute façon, espère que cela aide quelqu'un d'autre.

+0

J'aime cette extension, cependant, le 'this HtmlHelper helper' est étranger. Je l'ai changé en 'urlHelper url' et l'appelle en utilisant 'Url.ActionImageLink (...)' –

+0

Ou vous pouvez faire quelque chose comme 'var _url = new UrlHelper (htmlHelper.ViewContext.RequestContext) .Action (_actionName, _mergedRouteValues) ; 'obtenir un UrlHelper. J'ai volé sans vergogne ceci du lien @Tobi fourni. –

+0

@JimGilmartin Je vois, bonne idée. La seule raison pour laquelle j'ai mis le htmlhelper était que je pouvais l'utiliser de la même manière que n'importe quelle autre aide de rasoir, ce qui m'a évité d'essayer de me souvenir d'où il est stocké/accédé. – Jon

0

Ajout aux autres postes: dans mon cas (asp.net mvc 3) Je voulais un lien d'image pour agir comme un sélecteur de langue donc j'ai fini 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 intériorisation a été fait via une route linguistique - source originale here.

0

De bonnes solutions ici, mais que se passe-t-il si vous voulez en 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 le bouton-élément, mais vous pouvez mettre tout le code HTML que vous voulez là-dedans.

Et cela fonctionne avec l'aide Ajax ainsi: https://stackoverflow.com/a/19302438/961139