Depuis le tout début, ASP.NET MVC fournit des helpers permettant de créer des liens vers des actions ou des routes particulières. Et depuis le tout début, ces helpers n'autorisent rien d'autre que du texte. Si on veut mettre du html, il ne faut pas utiliser ces helpers (ou faire d'immondes bidouilles)
La solution la plus simple est de créer un simple lien html, en utilisant le Helper Url
<a href="@Url.Action("Index")"><img src="image.png"/></a>
Mais malheureusement, ceci n'est pas possible lorsqu'on veut créer des liens Ajax.
Vu que MVC est open-source, j'ai décidé d'aller voir un peu comment sont fait ces helpers, et d'en créer un nouveau, sur le modèle du BeginForm, permettant d'insérer du HTML dans un lien.
Le package MvcHtmlLink - permettant de créer des liens avec du html - est disponibles sur NuGet ; le code source et une mini doc sont sur GitHub
Le fonctionnement est simple : il faut créer un object IDisposable. Dans son constructeur on génère le tag d'ouverture, et dans le Dispose le tag de fermeture. Lorsqu'on l'utilise dans une vue Razor MVC avec un using, le html écrit entre les accolades sera donc au milieu de notre tag html.
@using (Html.BeginActionLink("Index", new { Id = 1 }, new { @class = "some-css-class" }))
{
<span>Html link</span>
}
va générer :
<a class="some-css-class" href="/Home/Index/1">Mvc RouteLink with params</a>
Pour faire ça, j'ai créé une classe HtmlLink :
public class HtmlLink : IDisposable
{
private readonly ViewContext _viewContext;
public HtmlLink(ViewContext viewContext, string targetUrl)
{
_viewContext = viewContext;
_viewContext.Writer.Write("<a href=\"" + targetUrl + "\">");
// Ici le lien doit être créé correctement, les attributs html et les options Ajax
}
public void Dispose()
{
_viewContext.Writer.Write("</a>");
}
}
Cette classe doit recevoir le ViewContext d'ASP.NET MVC, c'est ce qui va permettre d'écrire dans la page.
La façon dont est générée le lien est reprise du code d'ASP.NET, et est visible sur GitHub.
Pour pouvoir ensuite utiliser cette classe, on va créer les helpers. Pour qu'ils soient plus facile d'accès, on va les créer sous forme de méthodes d'extension de la classe HtmlHelper
, et dans le même namespace, afin qu'elles apparraissent sur l'objet @Html
et @Ajax
des vues MVC.
namespace System.Web.Mvc.Html
{
public static class HtmlLinkHelper
{
public static HtmlLink BeginActionLink(this HtmlHelper htmlHelper, string actionName, string controllerName)
{
string targerUrl = UrlHelper.GenerateUrl(null, actionName, controllerName, null, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
return new HtmlLink(htmlHelper, targetUrl);
}
public static HtmlLink BeginRouteLink(this HtmlHelper htmlHelper, string routeName)
{
string targerUrl = UrlHelper.GenerateUrl(null, routeName, null, null, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
return new HtmlLink(htmlHelper, targetUrl);
}
}
}
Je n'ai mis que deux exemples pour illustrer le principe, mais il faut créer toutes les différentes surcharges.
Cette fois c'est bon, notre helper peut être utilisé dans nos vues.
Si vous souhaitez créer des helpers de ce type, vous voyez donc que ce n'est pas compliqué, si vous souhaitez juste utiliser ces méthodes BeginActionLink ou BeginRouteLink, vous avez juste à référencer le package NuGet