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 le modèle de toutes les pages doit fournir comme le titre de la page, le nom de la page et l'emplacement où nous nous trouvons réellement pour un assistant HTML que j'ai fait qui effectue une action. De plus, chaque page a ses propres propriétés de modèle de vue.
Comment puis-je faire ceci? Il semble que ce soit une mauvaise idée de taper une mise en page mais comment puis-je transmettre ces informations?
asp.net-mvc-4
Rushino
la source
la source
ViewBag
. Peut-être une question de préférences. A voté pour votre commentaireRéponses:
Si vous devez transmettre les mêmes propriétés à chaque page, il serait judicieux de créer un modèle de vue de base utilisé par tous vos modèles de vue. Votre page de mise en page peut alors prendre ce modèle de base.
Si une logique est requise derrière ces données, celle-ci doit être placée dans un contrôleur de base utilisé par tous vos contrôleurs.
Il y a beaucoup de choses que vous pouvez faire, l'approche importante étant de ne pas répéter le même code à plusieurs endroits.
Edit: mise à jour à partir des commentaires ci-dessous
Voici un exemple simple pour démontrer le concept.
Créez un modèle de vue de base dont tous les modèles de vue hériteront.
Votre page de mise en page peut prendre cela comme modèle.
Enfin, définissez les données dans la méthode d'action.
la source
public class HomeController : BaseController
. De cette façon, le code commun n'a besoin d'être écrit qu'une seule fois et peut être appliqué à tous les contrôleurs.J'ai utilisé l'assistant html RenderAction pour razor dans la mise en page.
J'en avais besoin pour une chaîne simple. Donc, mon action renvoie une chaîne et l'écrit facilement. Mais si vous avez besoin de données complexes, vous pouvez renvoyer PartialViewResult et model.
Il vous suffit de mettre votre modèle au début de la vue partielle '_maPartialView.cshtml' que vous avez créée
Ensuite, vous pouvez utiliser les données du modèle dans cette vue partielle avec html.
la source
Une autre option consiste à créer une classe LayoutModel distincte avec toutes les propriétés dont vous aurez besoin dans la mise en page, puis à remplir une instance de cette classe dans ViewBag. J'utilise la méthode Controller.OnActionExecuting pour le remplir. Ensuite, au début de la mise en page, vous pouvez retirer cet objet de ViewBag et continuer à accéder à cet objet fortement typé.
la source
OnActionExecuting
. L'utilisation de ViewBag signifie également que vous perdez la sécurité du type dans votre contrôleur, ce n'est jamais une bonne chose.Vraisemblablement, le cas d'utilisation principal pour cela est d'obtenir un modèle de base dans la vue pour toutes (ou la majorité) des actions de contrôleur.
Compte tenu de cela, j'ai utilisé une combinaison de plusieurs de ces réponses, le soutien principal de la réponse de Colin Bacon.
Il est exact qu'il s'agit toujours de la logique du contrôleur car nous remplissons un modèle de vue pour revenir à une vue. Ainsi, le bon endroit pour le mettre est dans le contrôleur.
Nous voulons que cela se produise sur tous les contrôleurs car nous l'utilisons pour la page de mise en page. Je l'utilise pour des vues partielles qui sont rendues dans la page de mise en page.
Nous souhaitons é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 contrôleurs ViewModels hériteront respectivement de BaseViewModel et BaseController.
Le code:
BaseController
Notez l'utilisation de OnActionExecuted comme tiré de ce message SO
AccueilContrôleur
BaseViewModel
HomeViewModèle
Modèle de pied de page
Layout.cshtml
_Nav.cshtml
Espérons que cela aide.
la source
Vous n'avez pas à vous soucier des actions ou à modifier le modèle, utilisez simplement un contrôleur de base et transtypez le contrôleur existant à partir du contexte de la vue de disposition.
Créez un contrôleur de base avec les données communes souhaitées (titre / page / emplacement, etc.) et l'initialisation de l'action ...
Assurez-vous que chaque contrôleur utilise le contrôleur de base ...
Castez le contrôleur de base existant à partir du contexte de vue de votre
_Layout.cshml
page ...Vous pouvez maintenant faire référence aux valeurs de votre contrôleur de base à partir de votre page de mise en page.
METTRE À JOUR
Vous pouvez également créer une extension de page qui vous permettrait d'utiliser
this
.Ensuite, vous ne devez vous rappeler de l'utiliser que
this.Controller()
lorsque vous voulez le contrôleur.ou contrôleur spécifique qui hérite de
_BaseController
...la source
si vous voulez passer un modèle entier, procédez comme suit dans la mise en page:
et ajoutez ceci dans le contrôleur:
la source
Je ne pense pas qu'aucune de ces réponses ne soit suffisamment flexible pour une application de niveau grande entreprise. Je ne suis pas fan de la surutilisation du ViewBag, mais dans ce cas, pour plus de flexibilité, je ferais une exception. Voici ce que je ferais ...
Vous devriez avoir un contrôleur de base sur tous vos contrôleurs. Ajoutez vos données de mise en page OnActionExecuting dans votre contrôleur de base (ou OnActionExecuted si vous souhaitez différer cela) ...
Ensuite, dans votre _Layout.cshtml, tirez votre ViewModel du ViewBag ...
Ou...
Cela n'interfère pas avec le codage des contrôleurs de votre page ou des modèles d'affichage.
la source
MyLayoutViewModel
créée dynamiquement, comment puis-je passer certains paramètres à laOnActionExecuting
méthode?base.OnActionExecuting(filterContext)
dans votreOnActionExecuting
méthode !!!Créer une vue de base qui représente le modèle de vue Mise en page est une approche terrible. Imaginez que vous vouliez avoir un modèle qui représente la navigation définie dans la mise en page. Feriez-vous
CustomersViewModel : LayoutNavigationViewModel
? Pourquoi? Pourquoi devriez-vous transmettre les données du modèle de navigation à chaque modèle de vue unique que vous avez dans la solution?Le modèle de vue Mise en page doit être dédié, seul et ne doit pas forcer le reste des modèles de vue à en dépendre.
Au lieu de cela, vous pouvez le faire dans votre
_Layout.cshtml
fichier:Plus important encore, nous n'en avons pas besoin
new LayoutViewModel()
et nous obtiendrons toutes les dépendances quiLayoutViewModel
ont été résolues pour nous.par exemple
la source
Scoped
objet de modèle de disposition dans ASP..Net Core.D'autres réponses ont couvert à peu près tout sur la façon dont nous pouvons transmettre le modèle à notre page de mise en page. Mais j'ai trouvé un moyen de transmettre dynamiquement des variables à votre page de mise en page sans utiliser de modèle ni de vue partielle dans votre mise en page. Disons que vous avez ce modèle -
Et vous voulez obtenir dynamiquement la ville et l'état. Pour par exemple
dans votre index.cshtml vous pouvez mettre ces deux variables dans ViewBag
Et puis dans votre layout.cshtml, vous pouvez accéder à ces variables viewbag
la source
Il existe une autre façon de gérer cela. Ce n'est peut-être pas le moyen le plus propre d'un point de vue architectural, mais cela évite beaucoup de douleur associée aux autres réponses. Injectez simplement un service dans la disposition Razor, puis appelez une méthode qui obtient les données nécessaires:
Puis plus tard dans la vue de mise en page:
Encore une fois, pas propre en termes d'architecture (évidemment le service ne doit pas être injecté directement dans la vue), mais il fait le travail.
la source
@inject
est la meilleure solution, à mon avis.Vous pouvez également utiliser RenderSection , il vous aide à injecter vos
Model
données dans la_Layout
vue.Vous pouvez injecter des
View Model
données,Json
,Script
,CSS
,HTML
etc.Dans cet exemple, j'injecte
Json
de maIndex
vue àLayout
vue.Index.chtml
_Layout.cshtml
Cela élimine le besoin de créer une base séparée
View Model
.L'espoir aide quelqu'un.
la source
ce que j'ai fait est très simple et ça marche
Déclarez la propriété Static dans n'importe quel contrôleur ou vous pouvez créer une classe de données avec des valeurs statiques si vous le souhaitez:
Ces valeurs peuvent être mises à jour par les contrôleurs en fonction des opérations. plus tard, vous pourrez les utiliser dans votre _Layout
Dans _layout.cshtml
la source
Pourquoi personne n'a suggéré de méthodes d'extension sur ViewData?
Option 1
Cela me semble de loin la solution la moins intrusive et la plus simple au problème. Pas de chaînes codées en dur. Aucune restriction imposée. Pas de codage magique. Pas de code complexe.
Définir les données dans la page
Option 2
Une autre option, facilitant la déclaration du champ.
Définissez 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.
Option 3
Ensuite, vous pouvez combiner cela avec le renvoi d'un seul objet contenant tous les champs liés à la mise en page avec leurs valeurs par défaut.
Définir les données dans la page
Cette troisième option présente plusieurs avantages et je pense que c'est la meilleure option dans la plupart des cas:
Déclaration la plus simple des champs et des valeurs par défaut.
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 ViewData (par exemple, mise en page, en-tête, navigation).
Autorise du code et une logique supplémentaires dans la classe LayoutData.
PS N'oubliez pas d'ajouter l'espace de noms de ViewDataExtensions dans _ViewImports.cshtml
la source
Vous pouvez créer un fichier rasoir dans le dossier App_Code, puis y accéder à partir de vos pages d'affichage.
Projet> Repository / IdentityRepository.cs
Projet> App_Code / IdentityRepositoryViewFunctions.cshtml:
Projet> Views / Shared / _Layout.cshtml (ou tout autre fichier .cshtml)
la source
au lieu de passer par là, vous pouvez toujours utiliser une autre approche qui est également rapide
créer une nouvelle vue partielle dans le répertoire partagé et appeler votre vue partielle dans votre mise en page comme
dans votre vue partielle, vous pouvez appeler votre base de données et effectuer ce que vous voulez faire
en supposant que vous avez ajouté votre base de données Entity Framework
la source
C'est incroyable que personne n'ait dit cela ici. Passer un viewmodel à travers un contrôleur de base est un gâchis. Nous utilisons les revendications des utilisateurs pour transmettre des informations à la page de mise en page (pour afficher les données de l'utilisateur sur la barre de navigation par exemple). Il y a un autre avantage. Les données sont stockées via des cookies, il n'est donc pas nécessaire de récupérer les données dans chaque demande via des partiels. Faites juste quelques "revendications d'identité asp net" sur Google.
la source
Vous pouvez utiliser comme ceci:
la source