On peut supposer que le principal cas d'utilisation est l'obtention d'un modèle de base pour la vue pour toutes (ou la majorité) des actions du contrôleur.
J'ai donc utilisé une combinaison de plusieurs de ces réponses, en m'appuyant principalement sur la réponse de Colin Bacon.
Il est vrai qu'il s'agit toujours d'une logique de contrôleur, car nous remplissons un modèle de vue pour retourner à une vue. Ainsi, l'endroit correct pour placer ceci est dans le contrôleur.
Nous voulons que cela se produise sur tous les contrôleurs car nous l'utilisons pour la page de présentation. Je l'utilise pour les vues partielles qui sont rendues dans la page de mise en page.
Nous voulons également bénéficier de l'avantage supplémentaire d'un ViewModel fortement typé.
Ainsi, j'ai créé un BaseViewModel et un BaseController. Tous les ViewModel Controllers hériteront respectivement de BaseViewModel et de BaseController.
Le code :
Contrôleur de base
public class BaseController : Controller
{
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var model = filterContext.Controller.ViewData.Model as BaseViewModel;
model.AwesomeModelProperty = "Awesome Property Value";
model.FooterModel = this.getFooterModel();
}
protected FooterModel getFooterModel()
{
FooterModel model = new FooterModel();
model.FooterModelProperty = "OMG Becky!!! Another Awesome Property!";
}
}
Notez l'utilisation de OnActionExecuted tel que pris dans ce poste SO
AccueilContrôleur
public class HomeController : BaseController
{
public ActionResult Index(string id)
{
HomeIndexModel model = new HomeIndexModel();
// populate HomeIndexModel ...
return View(model);
}
}
BaseViewModel
public class BaseViewModel
{
public string AwesomeModelProperty { get; set; }
public FooterModel FooterModel { get; set; }
}
HomeViewModel
public class HomeIndexModel : BaseViewModel
{
public string FirstName { get; set; }
// other awesome properties
}
FooterModel
public class FooterModel
{
public string FooterModelProperty { get; set; }
}
Mise en page.cshtml
@model WebSite.Models.BaseViewModel
<!DOCTYPE html>
<html>
<head>
< ... meta tags and styles and whatnot ... >
</head>
<body>
<header>
@{ Html.RenderPartial("_Nav", Model.FooterModel.FooterModelProperty);}
</header>
<main>
<div class="container">
@RenderBody()
</div>
@{ Html.RenderPartial("_AnotherPartial", Model); }
@{ Html.RenderPartial("_Contact"); }
</main>
<footer>
@{ Html.RenderPartial("_Footer", Model.FooterModel); }
</footer>
< ... render scripts ... >
@RenderSection("scripts", required: false)
</body>
</html>
_Nav.cshtml
@model string
<nav>
<ul>
<li>
<a href="@Model" target="_blank">Mind Blown!</a>
</li>
</ul>
</nav>
J'espère que cela vous aidera.
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