135 votes

Transmettre des données à la mise en page qui sont communes à toutes les pages

J'ai un site web qui a une page de mise en page. Cependant, cette page de mise en page contient des données que toutes les pages doivent fournir, comme le titre de la page, le nom de la page et l'emplacement où nous nous trouvons actuellement pour une aide HTML que j'ai créée et qui effectue une action. De plus, chaque page a ses propres propriétés de modèle de vue.

Comment puis-je faire cela ? Il semble que ce ne soit pas une bonne idée de taper une mise en page mais comment puis-je passer ces informations ?

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 commentaire

0 votes

Pour mvc 5 voir cette réponse : stackoverflow.com/a/46783375/5519026

7voto

Andrew Points 745

Il y a une autre façon de gérer ça. Ce n'est peut-être pas le moyen le plus propre d'un point de vue architectural, mais il évite beaucoup de problèmes liés aux autres réponses. Il suffit d'injecter un service dans le layout Razor, puis d'appeler une méthode qui obtient les données nécessaires :

@inject IService myService

Puis, plus tard, dans la vue de la mise en page :

@if (await myService.GetBoolValue()) {
   // Good to go...
}

Encore une fois, ce n'est pas très propre en termes d'architecture (il est évident que le service ne doit pas être injecté directement dans la vue), mais cela fait l'affaire.

4voto

Yakir Manor Points 1725

Si vous voulez passer un modèle entier, faites comme ceci dans la mise en page :

@model ViewAsModelBase
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta charset="utf-8"/>
    <link href="http://stackoverflow.com/img/phytech_icon.ico" rel="shortcut icon" type="image/x-icon" />
    <title>@ViewBag.Title</title>
    @RenderSection("styles", required: false)    
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
    @RenderSection("scripts", required: false)
    @RenderSection("head", required: false)
</head>
<body>
    @Html.Action("_Header","Controller", new {model = Model})
    <section id="content">
        @RenderBody()
    </section>      
    @RenderSection("footer", required: false)
</body>
</html>

et ajoutez ceci dans le contrôleur :

public ActionResult _Header(ViewAsModelBase model)

4voto

Jack Sutherland Points 49

Je ne pense pas qu'aucune de ces réponses soit suffisamment flexible pour une grande application au niveau de l'entreprise. Je ne suis pas un fan de l'utilisation excessive du ViewBag, mais dans ce cas, pour des raisons de flexibilité, je ferais une exception. Voici ce que je ferais...

Vous devez avoir un contrôleur de base sur tous vos contrôleurs. Ajoutez vos données Layout OnActionExecuting dans votre contrôleur de base (ou OnActionExecuted si vous voulez différer cela)...

public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext     
        filterContext)
    {
        ViewBag.LayoutViewModel = MyLayoutViewModel;
    }
}

public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return View(homeModel);
    }
}

Puis dans votre _Layout.cshtml tirez votre ViewModel du ViewBag...

@{
  LayoutViewModel model = (LayoutViewModel)ViewBag.LayoutViewModel;
}

<h1>@model.Title</h1>

Ou...

<h1>@ViewBag.LayoutViewModel.Title</h1>

Cela n'interfère pas avec le codage des contrôleurs ou des modèles de vue de votre page.

4voto

Hristo Yankov Points 721

La création d'une vue de base qui représente le modèle de vue Layout est une approche terrible. Imaginez que vous vouliez avoir un modèle qui représente la navigation définie dans le layout. Feriez-vous CustomersViewModel : LayoutNavigationViewModel ? Pourquoi ? Pourquoi faire passer les données du modèle de navigation par chaque modèle de vue de la solution ?

Le modèle de vue Layout doit être dédié, en soi, et ne doit pas obliger le reste des modèles de vue à en dépendre.

Au lieu de cela, vous pouvez faire ceci, dans votre _Layout.cshtml fichier :

@{ var model = DependencyResolver.Current.GetService<MyNamespace.LayoutViewModel>(); }

Plus important encore, nous n'avons pas besoin new LayoutViewModel() et nous obtiendrons toutes les dépendances que LayoutViewModel a, résolu pour nous.

par exemple

public class LayoutViewModel
{
    private readonly DataContext dataContext;
    private readonly ApplicationUserManager userManager;

    public LayoutViewModel(DataContext dataContext, ApplicationUserManager userManager)
    {
    }
}

3voto

DarthVader Points 41

Les autres réponses ont couvert à peu près tout sur la façon dont nous pouvons passer le modèle à notre page de mise en page. Mais j'ai trouvé un moyen par lequel vous pouvez passer des variables à votre page de mise en page dynamiquement sans utiliser aucun modèle ou vue partielle dans votre mise en page. Disons que vous avez ce modèle -

public class SubLocationsViewModel
{
    public string city { get; set; }
    public string state { get; set; }
}

Et vous voulez obtenir la ville et l'état dynamiquement. Par exemple

dans votre index.cshtml vous pouvez mettre ces deux variables dans ViewBag

@model  MyProject.Models.ViewModel.SubLocationsViewModel
@{
    ViewBag.City = Model.city;
    ViewBag.State = Model.state;
}

Et ensuite, dans votre layout.cshtml, vous pouvez accéder à ces variables viewbag.

<div class="text-wrap">
    <div class="heading">@ViewBag.City @ViewBag.State</div>
</div>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X