Pourquoi personne n'a suggéré des méthodes d'extension sur les ViewData ?
Option 1
Il me semble que c'est de loin la solution la moins intrusive et la plus simple au problème. Pas de chaînes codées en dur. Pas de restrictions imposées. Pas de codage magique. Pas de code complexe.
public static class ViewDataExtensions
{
private const string TitleData = "Title";
public static void SetTitle<T>(this ViewDataDictionary<T> viewData, string value) => viewData[TitleData] = value;
public static string GetTitle<T>(this ViewDataDictionary<T> viewData) => (string)viewData[TitleData] ?? "";
}
Définir les données dans la page
ViewData.SetTitle("abc");
Option n° 2
Une autre option, qui facilite la déclaration sur le terrain.
public static class ViewDataExtensions
{
public static ViewDataField<string, V> Title<V>(this ViewDataDictionary<V> viewData) => new ViewDataField<string, V>(viewData, "Title", "");
}
public class ViewDataField<T,V>
{
private readonly ViewDataDictionary<V> _viewData;
private readonly string _field;
private readonly T _defaultValue;
public ViewDataField(ViewDataDictionary<V> viewData, string field, T defaultValue)
{
_viewData = viewData;
_field = field;
_defaultValue = defaultValue;
}
public T Value {
get => (T)(_viewData[_field] ?? _defaultValue);
set => _viewData[_field] = value;
}
}
Définir les données dans la page. La déclaration est plus facile que la première option, mais la syntaxe d'utilisation est légèrement plus longue.
ViewData.Title().Value = "abc";
Option n° 3
Vous pouvez ensuite combiner cela avec le retour d'un objet unique contenant tous les champs liés à la mise en page avec leurs valeurs par défaut.
public static class ViewDataExtensions
{
private const string LayoutField = "Layout";
public static LayoutData Layout<T>(this ViewDataDictionary<T> viewData) =>
(LayoutData)(viewData[LayoutField] ?? (viewData[LayoutField] = new LayoutData()));
}
public class LayoutData
{
public string Title { get; set; } = "";
}
Définir les données dans la page
var layout = ViewData.Layout();
layout.Title = "abc";
Cette troisième option présente plusieurs avantages et je pense qu'elle est la meilleure dans la plupart des cas :
-
Déclaration la plus simple des champs et des valeurs par défaut.
-
La syntaxe d'utilisation la plus simple lors de la définition de plusieurs champs.
-
Permet de définir différents types de données dans les ViewData (par exemple, Layout, Header, Navigation).
-
Permet d'ajouter du code et de la logique dans la classe LayoutData.
P.S. N'oubliez pas d'ajouter l'espace de nom de ViewDataExtensions dans _ViewImports.cshtml
12 votes
Pour tous ceux qui lisent les réponses ici, veuillez voir stackoverflow.com/a/21130867/706346 où vous verrez une solution beaucoup plus simple et plus propre que tout ce qui a été posté ici.
5 votes
@AvrohomYisroel bonne suggestion. Cependant, je préfère l'approche de @Colin Bacon parce qu'elle est fortement typée et qu'elle n'est pas dans l'approche de la
ViewBag
. Peut-être une question de préférences. J'ai quand même upvoted votre commentaire0 votes
Pour mvc 5 voir cette réponse : stackoverflow.com/a/46783375/5519026