ASP.NET MVC fournit par défaut des Helpers afin de générer du code HTML facilement. Il existe ainsi des helper pour la gestion des URLs, des inputs de formulaires, …
Une des bonnes pratiques est de créer des helpers perso afin de ne pas mettre de code C# directement dans la vue.
J’ai été confronté récemment dans mon projet à étendre un helper inclus de base dans ASP.NET MVC, celui des dropdownlist. En effet, je devais rendre éditable une liste select en fonction de mon modèle. Afin d’éviter d’avoir du code spaghetti dans ma page vue cshtml, j’ai étendu le Helper fournit par défaut afin de lui passer un paramètre supplémentaire, un booléen canEdit déterminant le statut éditable ou non de mon select.
Il existe 6 signatures pour la méthode DropDownListFor pour lesquelles j’ai ajouté mon paramètre. J’ai été confronté à une difficulté pour une des signatures qui passe en paramètres les attributs html sous la forme d’un objet. Il existe une méthode statique AnonymousObjectToHtmlAttributes qui permet de transformer votre objet en un dictionnaire (RouteValueDictionary) et il devient alors aisé de rajouter un attribut à votre select.
var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
attrs.Add("disabled", "disabled");
Le code complet (sans les commentaires API)
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, bool canEdit)
{
if (canEdit)
{
return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList);
}
var htmlAttributes = new Dictionary<string, object>();
htmlAttributes.Add("disabled", "disabled");
return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, htmlAttributes);
}
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, string optionLabel, bool canEdit)
{
if (!canEdit)
{
return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel);
}
var htmlAttributes = new Dictionary<string, object>();
htmlAttributes.Add("disabled", "disabled");
return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel, htmlAttributes);
}
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, string optionLabel, IDictionary<string, object> htmlAttributes, bool canEdit)
{
if (!canEdit)
{
htmlAttributes.Add("disabled", "disabled");
}
return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel, htmlAttributes);
}
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, IDictionary<string, object> htmlAttributes, bool canEdit)
{
if (!canEdit)
{
htmlAttributes.Add("disabled", "disabled");
}
return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, htmlAttributes);
}
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, object htmlAttributes, bool canEdit)
{
if (canEdit)
{
return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, htmlAttributes);
}
var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
attrs.Add("disabled", "disabled");
return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, attrs);
}
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, SelectList selectList, string optionLabel, object htmlAttributes, bool canEdit)
{
if (canEdit)
{
return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel, htmlAttributes);
}
var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
attrs.Add("disabled", "disabled");
return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel, attrs);
}
Et un petit exemple d’utilisation
@Html.DropDownListFor(x => x.MyPropId, new SelectList(Model.MyValues, "ValueId", "ValueName"), Model.User.IsAdmin || Model.User.HasEditRight)