Où et comment le fichier de disposition _ViewStart.cshtml est-il lié?

199

Voici le About.cshtml du modèle MVC 3 par défaut:

@{
    ViewBag.Title = "About Us";
}

<h2>About</h2>
<p>
     Put content here.
</p>

Je m'attendrais à ce qu'une référence au fichier _ViewStart soit trouvée dans le About.cshtml, mais ce n'est clairement pas le cas.

J'ai regardé dedans global.asaxet web.config, mais je ne peux pas découvrir comment le About.cshtmlfichier est "lié" avec la mise en page du fichier _ViewStart.

Tout fonctionne comme prévu, je voudrais juste savoir ce qui se passe sous le capot ...

Kman
la source

Réponses:

237

Du blog de ScottGu :

À partir de la version ASP.NET MVC 3 Beta, vous pouvez maintenant ajouter un fichier appelé _ViewStart.cshtml (ou _ViewStart.vbhtml pour VB) sous le dossier \ Views de votre projet:

Le fichier _ViewStart peut être utilisé pour définir le code de vue commun que vous souhaitez exécuter au début du rendu de chaque vue. Par exemple, nous pourrions écrire du code dans notre fichier _ViewStart.cshtml pour définir par programme la propriété Layout pour chaque vue comme étant le fichier SiteLayout.cshtml par défaut:

Étant donné que ce code s'exécute au début de chaque vue, nous n'avons plus besoin de définir explicitement la disposition dans aucun de nos fichiers de vue individuels (sauf si nous voulions remplacer la valeur par défaut ci-dessus).

Important: Étant donné que _ViewStart.cshtml nous permet d'écrire du code, nous pouvons éventuellement rendre notre logique de sélection de mise en page plus riche qu'un simple jeu de propriétés de base. Par exemple: nous pourrions faire varier le modèle de disposition que nous utilisons en fonction du type d'appareil accédant au site - et avoir une disposition optimisée pour téléphone ou tablette pour ces appareils, et une disposition optimisée pour les PC / ordinateurs portables. Ou si nous construisions un système CMS ou une application partagée commune utilisée par plusieurs clients, nous pourrions sélectionner différentes dispositions à utiliser en fonction du client (ou de son rôle) lors de l'accès au site.

Cela permet une grande flexibilité de l'interface utilisateur. Il vous permet également d'écrire plus facilement une seule fois la logique d'affichage et d'éviter de la répéter à plusieurs endroits.

Voir aussi ceci .

Jim Tollan
la source
14
C'est donc plus ou moins une fonctionnalité "codée en dur" de MVC3? Je n'ai pas besoin de la changer en une autre page "par défaut", juste curieuse de savoir comment elle a été configurée. Merci d'avoir trié tout ça :)
Kman
2
Kman- Hardcoded, par convention (choisissez un autre 'handle' ici :)) - donc oui, exactement. heureux qu'il ait dégagé le brouillard
jim tollan
Ce n'est pas seulement dans votre dossier "Vues" que vous pourriez en avoir besoin. Si vous ajoutez un RazorViewEngine personnalisé afin d'organiser les vues dans d'autres dossiers, vous devez également inclure le fichier à la racine de ces dossiers de vue alternatifs. Par exemple, j'ai déplacé toutes les vues du modèle Inspinia dans un dossier et l'ai exécuté dans le moteur de vue ViewLocationFormats = ViewLocationFormats.Union(new string[] { "~/Inspinia/ExampleViews/{1}/{0}.cshtml" }).ToArray();. Par conséquent, j'ai dû ajouter une copie de mon fichier _ViewStart.cshtml à "~ / Inspinia / ExampleViews", sinon il n'a pas été récupéré et aucune disposition n'a été définie.
Triynko
2
Si votre dossier Vues contient des sous-dossiers, pouvez-vous mettre un _ViewStartdans chaque sous-dossier qui sera lié aux vues de ce sous-dossier?
toddmo
35

Dans un sens plus général, cette capacité du framework MVC à "connaître" _Viewstart.cshtml est appelée "Codage par convention".

La convention sur la configuration (également connue sous le nom de codage par convention) est un paradigme de conception logicielle qui cherche à réduire le nombre de décisions que les développeurs doivent prendre, gagnant en simplicité, mais ne perdant pas nécessairement la flexibilité. L'expression signifie essentiellement qu'un développeur n'a besoin que de spécifier les aspects non conventionnels de l'application. Par exemple, s'il existe une classe Sale dans le modèle, la table correspondante dans la base de données est appelée «sales» par défaut. Ce n'est que si l'on s'écarte de cette convention, comme appeler la table «products_sold», qu'il faut écrire du code concernant ces noms.

Wikipédia

Il n'y a pas de magie. Il vient d'être écrit dans la base de code principale du framework MVC et est donc quelque chose que MVC "connaît". C'est pourquoi vous ne le trouvez pas dans les fichiers .config ou ailleurs; c'est en fait dans le code MVC. Vous pouvez cependant remplacer pour modifier ou annuler ces conventions.

rism
la source
13
Si MVC le sait, pourquoi Visual Studio ne le sait-il pas et ne me le fait-il pas remarquer? Si le codage par convention signifie que les choses fonctionnent tant que vous n'arrivez pas à briser la convention, ça craint en quelque sorte ...
Arne Evertsson
Ne pas enfreindre la convention est en quelque sorte le point. AKAIK Ruby on Rails suit également ce paradigme.
Umar Farooq Khawaja
+1 Raif. Il ne sert à rien de défendre un "codage par convention" mal documenté. Je pourrais dire cela à propos de n'importe lequel de mes codes inverses. "Quoi? Vous ne vous attendiez pas à ce qu'il tombe en panne quand il est arrivé à 33? Tout le monde sait que vous sautez 33." Malheureusement, l'écart de documentation pour ASP.NET MVC est énorme. Les seuls documents MS sont générés automatiquement sans résumé de source interne.
shannon
6
La convention sur la configuration ne signifie pas que vous ne pouvez pas la changer. Il DEVRAIT y avoir une configuration disponible pour pouvoir spécifier le nom et l'emplacement de ce fichier. Il peut très bien y en avoir, mais qui sait ce que c'est. Les gens utilisent le mantra "convention sur la configuration" pour couvrir une multitude de mauvaises décisions dans une base de code et ça m'a un peu énervé comme le gars qui vient après le fait pour maintenir leur désordre mal documenté qui "fonctionne juste" (mais À Dieu ne plaise, vous changez rien - vous passerez des heures à comprendre comment vous avez tout cassé).
Robert C.Barth
3
@AidenStrydom Je ne suis pas d'accord. La réponse acceptée me dit en fait comment utiliser _ViewStart. Cette réponse ne parle que d'un concept de design. Je suis venu ici pour des informations sur _ViewStart, pas pour savoir pourquoi Visual Studio ne voulait rien me dire sur _ViewStart.
Millie Smith
23

Juste une autre pensée.

Si vous voulez avoir votre propre cshtmlfichier comme modèle commun, vous pouvez le faire de cette façon

Dans votre, _viewstart.cshtmlvous pouvez mentionner votre cshtmlfichier commun .

@{Layout = "~/Views/Shared/_Layout.cshtml";}
user2515392
la source
14

Le code source est un bien meilleur endroit pour rechercher cela que la documentation.

Référençant le code MVC 6 de Github, nous avons quelques fichiers intéressants

----mettre à jour----

En raison des modifications de la structure source, les informations sur la façon dont les pages viewstart sont rassemblées peuvent désormais être trouvées dans RazorViewEngine.cs chercher la fonction "GetViewStartPages".

----/mettre à jour----

Pour répondre à la façon dont ils entrent en jeu, regardez RazorView , qui je crois (à cause d'IView) est lié au pipeline MVC. Ce fichier possède une méthode RenderAsync qui est appelée à partir du pipeline MVC pour rendre la vue demandée.

RenderAsync fait des appels à RenderPage ET ALORS RenderLayout (NOTEZ L'ORDRE). La RenderPage effectue d'abord des appels pour traiter les fichiers viewstart (notez au pluriel, il pourrait y avoir plus d'un fichier _viewstart).

Ainsi, les informations que vous recherchez peuvent être obtenues à partir de la fonction RenderViewStartAsync dans le fichier RazorView.cs sous l'espace de noms Microsoft.AspNet.Mvc.Razor.

Frison Alexander
la source
7

Cela peut ajouter des informations supplémentaires à cette question maintenant (2016 ala MVC4, MVC5).

Le moteur Razor recherche et exécute le code dans _ViewStart.cshtml avant tout autre code qui se trouve dans le même répertoire ou sous-répertoire où se trouve _ViewStart.cshtml .

Toute vue peut remplacer la propriété Layout ou l'une de ses valeurs.

J'ai pensé que je pourrais ajouter un peu plus d'informations pour vous montrer pourquoi c'est _ViewStart.

Si vous obtenez ILSpy et examinez le code dans RazorViewEngine (System.Web.Mvc.dll), vous verrez que le code lui-même fait référence à ce nom.

_ViewStart dans System.Web.Mvc.dll

Vous pouvez voir que RazorViewEngine recherche un fichier avec ce nom:

code moteur rasoir

RazorViewEngine.ViewStartFileName = "_ViewStart";
raddevus
la source
3
c'est ce que je cherchais, je déteste "ne sais pas" ce qui se passe dans mon projet, car je fais aussi mes propres modèles pour VS et ce fichier qui vient de sortir de l'air était très difficile à comprendre
Sebastian 506563
1

Si vous souhaitez avoir une mise en page commune pour vos pages, vous devez définir la mise en page commune et associer une vue à la mise en page, nous devons définir la propriété de mise en page sur chaque vue, cela viole le principe DRY (Don't Repeat Yourself). Pour cela .Net Framework a fourni le fichier "_ViewStart.cshtml", placé à l'intérieur du dossier de vue. Nous plaçons les informations de disposition dans le fichier "_ViewStart.cshtml" et chaque vue utilise par défaut ces informations de disposition. Si vous souhaitez donner des informations de mise en page différentes, supposons pour votre vue d'accueil, vous pouvez créer un nouveau "_ViewStart.cshtml" en référence à cette mise en page et le placer dans le dossier "Vue d'accueil".

KamalDeep
la source
1

La réponse courte est : ViewStarts démarre en premier lorsqu'une vue est rendue. La longue histoire est ci-dessous:

L'histoire de la création d'un fichier de vue unique:

  1. ViewStart est fusionné avec ViewImports puis exécuté en tant que fichier unique. Notez que ViewImports est toujours fusionné avec n'importe quel fichier cshtml, y compris le fichier ViewStart. Son but est d'abstraire les instructions @using et d'autres directives communes.
  2. La sortie de ViewStart (telle que Layout et ViewData) devient disponible pour le fichier View spécifique.
  3. Dans le fichier View, si la variable Layout est / devient nulle, le corps de la vue est rendu et la sortie finale est livrée à l'utilisateur.
  4. Si la variable de mise en page est / devient non nulle, l'exécution est déplacée vers le fichier de mise en page qui à son tour est fusionné avec ViewImports en tant que fichier unique, puis à l'instruction @RenderBody () à l'intérieur de l'exécution du fichier de mise en page est replacée dans le fichier de vue qui est à nouveau fusionné avec ViewImports et la sortie est fusionnée avec le fichier de mise en page à l'emplacement de @RenderBody () et la sortie finale est finalement livrée à l'utilisateur.

J'espère que cela vous fera prendre conscience de ce qui se passe réellement à l'intérieur des mystères inconnus du cycle de vie de votre programme.

Shadi Namrouti
la source