1
votes

I'm new to MVC Development and have started a new MVC 4 application to build a sort of Personal Portfolio for practice. I cannot figure out why my _Layout.cshtml is not rendering within my home or default View though. I've already checked the following:

  1. The App_Start/RouteConfig.cs file has not been modified since the application was created.
  2. The Views/Shared/_ViewStart.cshtml has the following (default):

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

Views/Shared/_Layout.cshtml:

        <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale = 1.0" />
            <title>Portfolio</title>
            @Styles.Render("~/Content/css")
            @Scripts.Render("~/bundles/jquery")
            @Scripts.Render("~/bundles/bootstrapjs")
            @Scripts.Render("~/bundles/customJs")
            <link href="~/Content/bootstrap.css" rel="stylesheet" />
            <link href="~/Content/bootstrapMod.css" rel="stylesheet" />
            <link href="~/Content/Site.css" rel="stylesheet" />
        </head>
        <body style=""zoom: 1">
            <div class="container mainContent">
                <div class="page-header hidden-sm hidden-xs">
                    @Html.Partial("_Header")
                </div>

                <nav id="navBar" class="navbar navbar-default" role="navigation">
                    <div class="container-fluid">
                        <!-- Brand and toggle get grouped for better mobile display -->
                        <div class="navbar-header">
                            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse">
                                &#9776;
                            </button>
                            <a class="navbar-brand hidden-lg hidden-md" href="/Home">Portfolio</a>
                        </div>

                        <!-- Collect the nav links, forms, and other content for toggling -->
                        <div class="collapse navbar-collapse" id="navbar-collapse">                    
                           @*@Html.MvcSiteMap().Menu()*@

                        </div>
                    </div>
                </nav>

                <div class="container">
                    @RenderSection("scripts", required:false)

                    <div class="pageTitle largeFontSize">
                        @ViewBag.HeaderTitle
                    </div>

                    @RenderBody()
                </div>


            </div>
            <div id="footer">
                Copyright 2014 - Portfolio - <a target="_blank" href="/terms-and-conditions-of-us.html">Website Terms &amp; Conditions of Use</a>
            </div>
        </body>
    </html>

~/Views/Shared/_Header.cshtml

<div class="row">
    <div class="col-md-6">
        <div>
            <a href="~/Home">
                <img src="~/Content/Images/Header.png" class="img-responsive"/>
            </a>
        </div>
    </div>
    <div class="col-md-6 box">
        @if (Request.IsAuthenticated)
        {
            <div class="profileLinks">                    
                <a href="#">My Projects</a>
                |
                <a href="#">Contact Profile</a>
            </div>

            <div class="content logout">                
                <div class="row">
                    <div>
                        Hi, @User.Identity.Name
                        @Html.ActionLink("Log Off", "LogOff", "Account", new {},new { @class = "btn btn-primary btn-sm" })
                    </div>
                </div>                
            </div>
        }
        else
        {
            <div class="content">
                <div class="row">
                    <div class="col-md-4">
                        <input type="text" id="username" placeholder="E-mail" required tabindex="1"/>
                        <a href="#" ><h6>Forgot your username?</h6></a>
                    </div>
                    <div class="col-md-4">
                        <input type="password" id="password" placeholder="Password" required tabindex="2" onkeyup="EnterKeyPressed()"/>
                        <a href="#" ><h6>Forgot your password?</h6></a>
                    </div>
                    <div class="col-md-4">
                        <input type="button" id="loginButton" value="Login" onclick="login()" class="btn btn-primary btn-sm" tabindex="3" onkeyup="EnterKeyPressed()"/>
                        <br />
                        <input type="checkbox" id="rememberMe">Remember Me
                    </div>
                </div>
            </div>
        }
    </div>
</div>

My Default View below loads, but with nothing present. The title changes to "Index", and the rest is a blank page. Shouldn't the ~/Views/Shared/_Layout.cshtml be rendering within this page in some manner?

With what I have currently set-up, when the shared _Layout.cshtml loads within my Home/Index/ View, I should see the Header image I have created and sourced on the shared view.

Views/Home/Indx.cshtml

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div>

    </div>
</body>
</html>

When I try Layout = "~/Views/Shared/_Layout.chtml"; it errors out saying it could not be found at the designated path. I was semi-working off an example a Developer friend sent me, and with it they are not explicitly setting the Layout?

3

3 Answers

8
votes

Couple of things...

If you have a view you are trying to render in a shared view then you do not need any of the HTML layout elements contained within the view you are putting it into. Lets start with really basic.

View start

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

_Layout.cshtml

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
</head>
<body>
    @RenderBody()
</body>
</html>

Home View

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

Now the home view gets plonked into where @RenderBody() appears. So index will be a heading 2 in the page. The title is passed in the ViewBag object and set as the page title in the _Layout.cshtml file with the following @ViewBag.Title

5
votes

Get rid of the following in your Index.cshtml

@{
    Layout = null;
}

This code is telling the rendering engine to use no shared layout. You also won't need any of the HTML pre-amble (HTML, HEAD or BODY tag) in the Index.

1
votes

Remove

@{ Layout = null } 

or explicitly set it to "~/Views/Shared/_Layout.cshtml"; This is less preferable though.

It is overriding the _ViewStart behavior.

Also, you will not need to include the tags in your index.cshtml view because they are included with your _Layout.cshtml.

Essentially what is happening is you are creating a wrapper page with _Layout where you put content that is common across your website (e.g. Header, footer, some navigation). Then you create a view, in this case index.cshtml, that forms the body of the page. _Layout.cshtml and Index.cshtml get compiled into a single page, with _Layout.cshtml acting like a wrapper around Index.cshtml.