Presumibilmente, il caso d'uso principale per questo è ottenere un modello di base nella vista per tutte (o la maggior parte delle) azioni del controller.
Detto questo, ho usato una combinazione di molte di queste risposte, supporto principale per la risposta di Colin Bacon.
È corretto che questa sia ancora logica del controller perché stiamo popolando un viewmodel per tornare a una vista. Quindi il posto corretto per metterlo è nel controller.
Vogliamo che ciò accada su tutti i controller perché lo usiamo per la pagina di layout. Lo sto usando per le viste parziali che vengono visualizzate nella pagina del layout.
Vogliamo anche ancora il vantaggio aggiuntivo di un ViewModel fortemente tipizzato
Pertanto, ho creato BaseViewModel e BaseController. Tutti i controller ViewModels erediteranno rispettivamente da BaseViewModel e BaseController.
Il codice:
BaseController
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!";
}
}
Nota l'uso di OnActionExecuted come tratto da questo post SO
HomeController
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; }
}
Layout.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>
Si spera che questo aiuti.