0

I am beginner in MVC and trying to redirect Admin into _Layout - admin.cshtml after login successfully, because I have different options in admin navbar. I have logged in and redirect the layout into _Layout - admin.cshtml successfully. But, when I clicked on Gallery option my layout again moves into the previous _Layout.cshtml. Which is not correct.

Anybody can suggest me, how can I resolve this issue?

_Layout - admin.cshtml

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - SS General Trading</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")

</head>
<body>
        @RenderPage("~/Views/Shared/Navbar-admin.cshtml")
    <div>
        @RenderBody()
        <hr />
        <footer style="margin-top:-50px; z-index:999" class="site-footer">
            <div class="row">
    <div style="border-right:groove" class="col-md-4">

    </div>
    <div style="border-right:groove" class="col-md-4">

    </div>
    <div class="col-md-4">
    </div>
            </div>
        </footer>
    </div>


    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

Navbar-admin.cshtml

@{ Layout = null; } 
<!DOCTYPE HTML>
<html lang="en">
<head>
    -------- some code
</head>
<body>
    <!-- header-top -->
    <div class="header-top">
        ------- some code
            <div class="top-nav">
                <nav class="navbar navbar-default">
                    <div class="container">
                        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                            Menu
                        </button>
                    </div>
                    <!-- Collect the nav links, forms, and other content for toggling -->
                    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                        <ul class="nav navbar-nav">
                            <li class="home-icon"><a href="index.html"><span class="fa fa-home" aria-hidden="true"></span></a></li>
                            <li>@Html.ActionLink("News", "Index", "News_Events")</li>
                            <li>@Html.ActionLink("Gallery", "Index", "Galleries")</li>
                            @Html.Partial("_LoginPartial")
                         </ul>
                    </div>

                        <div class="clearfix"> </div>
                    </div>
                </nav>
            </div>
        </div>
        <!-- //container -->
    </div>
    </body>
</html>

_ViewStart.cshtml

@{
    if (this.User.IsInRole("Admin"))
    {
        Layout = "~/views/shared/_layout - admin.cshtml";
    }
    else
    {
        Layout = "~/Views/Shared/_Layout.cshtml";

    }

}
nabia saroosh
  • 399
  • 1
  • 14
  • 36

3 Answers3

2

You can't redirect to a layout - see explanation of layout below.
You need to redirect to a page which is using the layout - in your case, Index.cshtml.

Layout basics:

ASP.NET MVC has a Layout view which contains common UI parts, so that we don't have to write the same code in every page. The markup of a view which uses a layout will be embedded into layout markup at this line:

@RenderBody()

This is where some particular page will be embedded. The reason you are getting your error is because when you try redirecting to layout, it doesn't know what it should render as the content.

Look at your Index.cshtml

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

When you redirect to Index.cshtml, it means that the markup of this particular view Index.html will be embedded into the layout _Layout - admin.cshtml at the RenderBody() line.

Thats the basic concept.

Your situation :

If you want to include some admin-only navbar (should read: render additional stuff based on some condition), you could do conditional rendering:

Include some logic in the layout:

<!-- only render navbar for admins!-->
@If(User.IsAuthenticated && User.IsInRole("Admin"){
    Html.RenderPartial("~/Views/Shared/Navbar-admin.cshtml");
}

And the navbar will render only for admins.
I believe you should use Html.RenderPartial("your navbar") instead of RenderPage(). Why

@Chris Pratt answer could be a better solution in some cases, since it will allow you to keep your layout clean (no @if trees) when you have a bunch of admin stuff floating around - but you will duplicate some code.

evictednoise
  • 587
  • 1
  • 7
  • 19
1

If you have a different layout for admins, the best way to handle that is with a _ViewStart.cshtml. Simply add that to your Views folder in your project, with something like the following:

@{
    Layout = User.IsAuthenticated && User.IsInRole("Admin")
        ? "~/Views/Shared/_Layout - admin.cshtml"
        : "~/Views/Shared/_Layout.cshtml";
}

_ViewStart.cshtml basically sets the default for all views in the folder it's in or any folders under that folder. Here, then, we're setting the default layout based on whether a user is logged in as an admin or not.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
0

I have solved my problem by adding

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

this line in ~/Views/Galleries/index.cshtml.

nabia saroosh
  • 399
  • 1
  • 14
  • 36