Par défaut, le nouveau modèle de projet pour ASP.NET MVC 3 ajoute ce qui suit à la disposition par défaut (page principale dans le rasoir):
<title>@ViewBag.Title</title>
La vue doit alors contenir les éléments suivants pour affecter le titre de la page, par exemple:
@{
ViewBag.Title = "Log On";
}
C'est peut-être juste ma préférence, mais je trouve que l'utilisation du ViewBag pour détenir un peu le titre (je pense trop de saveur de chaîne magique). Ma question est donc: est-ce la meilleure pratique recommandée pour les personnes utilisant ASP.NET MVC 3 et le rasoir (en utilisant un sac de propriétés dynamiques) ou optez-vous pour quelque chose de plus fortement typé (impliquant peut-être une classe de base personnalisée?)
Je ne pense pas qu'il y ait quelque chose de mal avec la fonction de gestion de titre par défaut fournie avec asp.net MVC 3, c'est correct.
Personnellement, je fais cela (écrit ci-dessous) pour gérer le titre, je n'approuve pas le code ci-dessous ou dire que c'est mieux que la fonctionnalité par défaut, c'est juste une préférence.
Maître
<title>
@RenderSection("Title");
</title>
Vue
@section Title
{
write title
}
ne chose que je pourrais suggérer pour améliorer la fonctionnalité par défaut
@{
string pageTitle = @ViewBag.Title ?? "Title Not Set";
}
<title>@pageTitle</title>
Donc, chaque fois que vous oubliez de l'ajouter dans viewbag, la page affichera title = Title Not Set
La création d'une classe de base puis l'héritage de tous vos contrôleurs de cette classe de base peut également être effectué. Mais je pense que cela prend tellement de peine pour title
.
ViewBag pour le titre est parfaitement bien (je dirais même que c'est le but d'avoir ViewBag) - la dynamique n'est pas le mal absolu. Le "titre" est bien connu, peu susceptible de changer et même prédéfini dans les modèles de vue. J'utilise personnellement le titre suivant:
<title>@(ViewBag.Title == null ? string.Empty : ViewBag.Title + " | ")Site Name</title>
Si vous craignez de mal saisir ViewBag.Title
, Vous pouvez le rendre fort en créant WebViewPage
personnalisé, mais vous devrez toujours utiliser ViewBag
ou peut-être HttpContext.Items
À l'intérieur propriété fortement typée car il existe plusieurs instances de WebViewPage
créées lors du rendu IIRC.
Je recommanderais de rester avec ViewBag
, en créant votre propre WebViewPage
à cause de cela semble exagéré - même créer une seule propriété dessus si vous avez déjà personnalisé WebViewPage
est à mon avis juste une complication sans valeur - et cela vient d'une personne qui est souvent trop ingénieuse.
Je n'utilise pas non plus le ViewBag.
En haut de _Layout.shtml ...
@model <YourWebAppNameSpace>.Models.Base.EveryPageViewModel
Dans _Layout.shtml ...
<title>@Model.Title</title>
Dans votre modèle ...
/// <summary>
/// Index View Model
/// </summary>
public class IndexViewViewModel : EveryPageViewModel {
}
Dans EveryPageViewModel
/// <summary>
/// Every Page View Model
/// </summary>
public abstract class EveryPageViewModel {
/// <summary>
/// Title
/// </summary>
public string Title { get; set; }
/// <summary>
/// Sub Title
/// </summary>
public string SubTitle { get; set; }
}
Dans l'action de votre contrôleur
/// <summary>
/// Index
/// </summary>
/// <returns></returns>
public ActionResult Index() {
var model = new IndexViewViewModel();
model.Title = "Home";
return View(model);
}
J'aime créer un attribut ActionFilter PageTitle plutôt que de modifier des ViewBags individuels
Utilisation: conservez la même vue
<title>@ViewBag.Title</title>
Pour le titre de page à l'échelle du contrôleur:
[PageTitle("Manage Users")]
public class UsersController : Controller {
//actions here
}
Pour des vues individuelles:
public class UsersController : Controller {
[PageTitle("Edit Users")]
public ActionResult Edit(int id) {
//method here
}
}
Code d'attribut:
public class PageTitleAttribute : ActionFilterAttribute
{
private readonly string _pageTitle;
public PageTitleAttribute(string pageTitle)
{
_pageTitle = pageTitle;
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var result = filterContext.Result as ViewResult;
if (result != null)
{
result.ViewBag.Title = _pageTitle;
}
}
}
Facile à gérer et fonctionne comme un charme.
Pour moi personnellement, je pense que ce cas est une utilisation acceptable de ViewBag
. Il est limité à une propriété "bien connue" et ne causera probablement aucun problème à l'avenir. En fin de compte, il s'agit d'être pragmatique et de trouver un moyen d'être aussi rapide que possible. Avoir une classe de base où vous devez définir le titre serait à mon avis trop de code pour valoir le type de sécurité.
Bonne chance!
Il n'y a rien de mal à utiliser ViewBag.Title = "My Title";
Tout ce que vous faites, c'est utiliser une propriété dynamique.
La question est vraiment de savoir où les informations doivent être "déclarées".
C'est-à-dire, où est-il le plus accessible pour les fins à portée de main.
Si c'est par page, c'est le bon endroit.
Si, cependant, le titre de la page peut être dérivé du modèle, vous devez le faire.
Dans ce cas, j'utiliserais probablement une classe de base pour le ViewModel que vous utilisez et j'y créerais une propriété PageTitle qui contient la logique pour dériver le titre de la page à partir des propriétés du modèle.
Alors:
<title>Model.PageTitle</title>
En résumé, les chevaux pour les cours et n'ayez pas peur d'utiliser des propriétés dynamiques ... tant que vous comprenez ce qu'ils sont et ce qu'ils font.
Je dirais que tant que ce n'est que le titre que vous souhaitez définir, vous pouvez utiliser le ViewBag. Eh bien, peut-être pas seulement - au plus 2-3 propriétés.
Mais si vous commencez à voir que vous définissez de plus en plus de propriétés (communes) dans chaque action du contrôleur, j'irais avec une "classe ViewModelBase" fortement typée. Mais c'est juste moi.
nous préférons un réglage de titre fort .. quelques exemples de notre classe BaseController. (La page définit la vue modale encapsulée)
protected override ViewResult View(string viewName, string masterName, object model)
{
if (model is Page)
{
ViewBag.Title = ((Page)model).Title;
//HACK: SEO
//TODO: SEO
}
return base.View(viewName, masterName, model);
}