简体   繁体   中英

how to load a different _layout.cshtml depending on role?

My app will have different roles, one role will be the Global Administrator, which will have options like adding users, adding companies, etc.

The template I bought has one _layout.cshtml, however I need that it loads a different one depending on the role of the user.

One which has a very different menu.

My viewstart

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

and my layouts.cshtml

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <title>INSPINIA | @ViewBag.Title</title>

    <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700' rel='stylesheet' type='text/css'>
    <!-- Add local styles, mostly for plugins css file -->
    @if (IsSectionDefined("Styles"))
        {@RenderSection("Styles", required: false)}

    <!-- Add jQuery Style direct - used for jQGrid plugin -->
    <link href="@Url.Content("~/Scripts/plugins/jquery-ui/jquery-ui.css")" rel="stylesheet" type="text/css" />

    <!-- Primary Inspinia style -->     
    @Styles.Render("~/font-awesome/css")                                                
    @Styles.Render("~/Content/css")
</head>
<body>

    <!-- Skin configuration box -->
    @Html.Partial("_SkinConfig")

    <!-- Wrapper-->
    <!-- PageClass give you ability to specify custom style for specific view based on action -->
    <div id="wrapper" class="@Html.PageClass()">

        <!-- Navigation -->
        @Html.Partial("_Navigation")

        <!-- Page wraper -->
        <div id="page-wrapper" class="gray-bg @ViewBag.SpecialClass">

            <!-- Top Navbar -->
            @Html.Partial("_TopNavbar")

            <!-- Main view  -->
            @RenderBody()

            <!-- Footer -->
            @Html.Partial("_Footer")

        </div>
        <!-- End page wrapper-->

        <!-- Right Sidebar -->
        @Html.Partial("_RightSidebar")

    </div>
    <!-- End wrapper-->

    <!-- Section for main scripts render -->
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @Scripts.Render("~/plugins/slimScroll")
    @Scripts.Render("~/bundles/inspinia")

    <!-- Skin config script - only for demo purpose-->
    @Scripts.Render("~/bundles/skinConfig")

    <!-- Handler for local scripts -->
    @RenderSection("scripts", required: false)
</body>
</html>

Everything works perfect, but I need to create another layouts.cshtml with a reference to a different navigation partial view and thats where the question comes in,

How can I make the app to load that specific layouts.csthml when the user belongs to a specific role?

This answer assumes you are using SimpleMembership's default role manager in MVC4:

If it is just a specific section of the layout you can use Razor. Put this where your menu code is... (which is probably in _Navigation):

@if (Roles.IsUserInRole("GlobalAdmin"))
{
    @Html.ActionLink("Admin only link", "ActionName", "ControllerName")
    @Html.ActionLink("Another admin link", "ActionName", "ControllerName")
}

If it is from a specific action method, you can specify a layout:

string layoutName = Roles.IsUserInRole("GlobalAdmin") ? "_LayoutAdmin" : "_Layout";
return View(model, layoutName);

You can automate this last method by using a custom actionresult or maybe even an action filter.

You can use Area . Implement the AreaRegistration abstract class class is a good start. In Global.asax , Application_Start() register all the areas you have

AreaRegistration.RegisterAllAreas()

Have two MVC projects say one Something.Admin, and the other Something.Web

This tutorial is good but everything is in one project I like different projects http://www.codeproject.com/Articles/714356/Areas-in-ASP-NET-MVC

You can split the layout into two parts one for Normal users and other for Admin. Then there are two or three types of way to render those layouts as specified in this article using _ViewStart.cshtml, or Specifying the layout in View or via Action result.

One option is to use MvcSiteMapProvider and the included security trimming feature to show/hide the different menu options depending on who is signed in. It is based on the MVC AuthorizeAttribute or any subclass of it so it will support any combination of users, roles, or custom security claims you may already have defined.

If you prefer not to use a 3rd party library, another option is to reverse engineer the AuthorizeAttributeAclModule to build your own system that is based on the MVC AuthorizeAttribute .

Full Disclosure

I am a major contributor of MvcSiteMapProvider .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM