Comment spécifier différentes dispositions dans le fichier ViewStart du rasoir ASP.NET MVC 3?

313

Je voudrais avoir 2 mises en page distinctes dans ma candidature. Disons que l'un est destiné à la section publique du site Web et l'autre à la partie réservée aux membres.

Pour plus de simplicité, disons que toute la logique de chacun de ces sites est soigneusement emballée dans 2 contrôleurs distincts.

  • PublicController
  • StaffController

Et qu'ils ont chacun une disposition correspondante pour toutes les vues sous chacun.

  • _PublicLayout.cshtml
  • _StaffLayout.cshtml

Comment utiliser le fichier _ViewStart.cshtml pour spécifier que tous les View / Action sous "Public" utilisent le PublicLayout et tout sous "Staff" utilisent le StaffLayout?

Merci!

Justin
la source
4
Juste au cas où: si vous souhaitez supprimer la mise en page pour une Razorvue donnée , définissez simplementLayout = null;
Leniel Maccaferri
3
Juste pour commenter votre exemple, vous ne devriez probablement pas avoir de contrôleurs nommés Public et Personnel. Les contrôleurs sont le plus souvent implémentés comme point d'entrée d'une action de type CRUD sur certaines entités commerciales clés, comme EventController, UserController, ou similaires. Si votre candidature est assez importante, la responsabilité d'un contrôleur public / personnel serait bien trop large. Considérez plutôt les zones. msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspx Vous en êtes peut-être conscient, mais quelqu'un d'autre qui le lit peut avoir une mauvaise idée, donc pour l'enregistrement.
Alex

Réponses:

558

Vous pouvez mettre un _ViewStart.cshtmlfichier dans le /Views/Publicdossier qui remplacerait celui par défaut dans le /Viewsdossier et spécifier la mise en page souhaitée:

@{
    Layout = "~/Views/Shared/_PublicLayout.cshtml";
}

Par analogie, vous pouvez mettre un autre _ViewStart.cshtmlfichier dans le /Views/Staffdossier avec:

@{
    Layout = "~/Views/Shared/_StaffLayout.cshtml";
}

Vous pouvez également spécifier la disposition à utiliser lors du retour d'une vue à l'intérieur d'une action de contrôleur, mais c'est par action:

return View("Index", "~/Views/Shared/_StaffLayout.cshtml", someViewModel);

Encore une autre possibilité est un filtre d'action personnalisé qui remplacerait la disposition. Comme vous pouvez voir de nombreuses possibilités pour y parvenir. A vous de choisir celui qui correspond le mieux à votre scénario.


METTRE À JOUR:

Comme demandé dans la section des commentaires, voici un exemple de filtre d'action qui choisirait une page maître:

public class LayoutInjecterAttribute : ActionFilterAttribute
{
    private readonly string _masterName;
    public LayoutInjecterAttribute(string masterName)
    {
        _masterName = masterName;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.MasterName = _masterName;
        }
    }
}

puis décorez un contrôleur ou une action avec cet attribut personnalisé en spécifiant la disposition souhaitée:

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
    return View();
}
Darin Dimitrov
la source
1
@DarinDimitrov Où je vais créer LayoutInjecterAttribute. ? Y a-t-il un endroit particulier?
kbvishnu
2
@VeeKeyBee, vous pouvez le placer dans un ActionFilterssous-dossier.
Darin Dimitrov
Un problème potentiel avec LayoutInjecterAttribute: Il est appelé avant la OnExceptionméthode du contrôleur . Ainsi, si le contrôleur fournit un résultat d'affichage lors de la gestion des exceptions, la disposition ne sera pas définie.
Jeff Sharp
En tant que nouveau mec de MVC, je voudrais dire merci de m'avoir beaucoup appris dans cette réponse. Cependant, je ne comprends pas ce qui se passe à l'intérieur OnActionExecuted. Pouvez-vous s'il vous plaît mettre à jour la réponse pour moi.
Imad
29

Une autre méthode consiste à définir la disposition à l'intérieur de la vue:

   @{
    Layout = "~/Views/Shared/_MyAdminLayout.cshtml";
    }

Plus de façons de faire, peuvent être trouvées ici , j'espère que cela aide quelqu'un.

shaijut
la source
1
Cela ne fonctionnera pas - sans le _ViewStart.cshtml séparé, votre vue sera toujours rendue à l'intérieur de la méthode @RenderBody () dans l'autre mise en page.
Tillman32
Ce! Pourquoi tout le monde propose-t-il ces processus extrêmement complexes alors que tout ce que vous avez à faire est le suivant!
George Harnwell
15

Cette méthode est le moyen le plus simple pour les débutants de contrôler le rendu des mises en page dans votre application ASP.NET MVC. Nous pouvons identifier le contrôleur et rendre les mises en page en tant que contrôleur par, pour ce faire, nous pouvons écrire notre code dans le fichier _ViewStart dans le répertoire racine du dossier Views. Voici un exemple qui montre comment cela peut être fait.

@{
    var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
    string cLayout = "";

    if (controller == "Webmaster")
        cLayout = "~/Views/Shared/_WebmasterLayout.cshtml";
    else
        cLayout = "~/Views/Shared/_Layout.cshtml";

    Layout = cLayout;
}

Lire l'article complet ici "Comment rendre une disposition différente dans ASP.NET MVC"

Anil Sharma
la source