GPGVM
GPGVM

Reputation: 5619

New to MVC can't get layout to work as desired

I am trying to implement what I think is a pretty standard "dashboard" layout. The trick is I know ASP.NET but not so familiar with MVC so this is a learning project.

I have read many an article and they have helped me progress right to the point where I am very stuck and confused.

Part of my confusion comes from an existing advanced MVC project that I am familiar with from a user perspective. This helps in that I am able to pick through the source code and match up what I am learning to what I have seen from the user perspective.


This is not the problem just an example...

For example I read here what I believe is a very good introduction to the concepts. (http://www.codeproject.com/Articles/383145/RenderBody-RenderPage-and-RenderSection-methods-in)

In the MVC project I get to pick through however I see in the _Layout

@if (IsSectionDefined("statusbar"))
{
   @RenderSection("statusbar")
}

however @section statusbar is not defined in the _Layout. If I do a global search for @section I find this:

@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@section header
{
}
@section headermenu
{
}
@section statusbar
{
}
@RenderBody()

So am I correct in guessing that statusbar is defined but it is an empty shell?

If it is an empty shell how does it get populated...cause when the project is running the statusbar does indeed have information???

So again this isn't my problem it is just an example of how the information at hand is confusing me.


This IS the problem:I'm not sure when to use PartialView, RenderSection...etc

My layout renders goofy. What is goofy? The only thing I can think of is to show you a screenshot of what happens.

Unexpected Behaviour

What I want...

Good behaviour


Here is the code used to generate these pages. The tags etc. for bootstrap etc. are omitted for brevity.

_Layout.cshtml

<!DOCTYPE html>
<html lang="en">
<head>
    <title>@PageTitle</title>
</head>
<body>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-12">
                Header Stuff
            </div>
        </div>

        <div class="row">
            <div class="col-md-4">
                @RenderBody()
            </div>
            <div class="col-md-8">
                Main Content
            </div>
        </div>

        <div class="row">
            <div class="col-md-12">
                Footer Stuff
            </div>
        </div>
    </div>
</body>
</html>

Index.cshtml

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

<div class="col-md-1">
<nav id="Navbar" class="navbar navbar-left" role="navigation">
    <div id="organizer">
        @(Html.Kendo().PanelBar()....etc....)
    </div>
</nav>
</div>
<div class="col-md-3">
 This is a place holder for my subnav...????
</div>

Stuff1Link cshtml

@model StuffModel

<div style="height:400px; border:dashed; border-width:thick;">
@{ Html.Kendo().MobileLayout().Name("mlay_PropStatus"); }
@(Html.Kendo().MobileView().....
</div>

Upvotes: 0

Views: 413

Answers (3)

Ali reza Soleimani Asl
Ali reza Soleimani Asl

Reputation: 167

1.If your view just has some Html code just use "PartialView" :

@Html.Partial("_theLastPost")

2.If your view has controller for passing data it's better use "RenderAction":

@{ Html.RenderAction("_theLastPost"); }

and its controller

public PartialViewResult _theLastPost()
    {
        var a = (from c in db.Posts
                 orderby c.ID_Post descending
                 select c);
        return PartialView(a);
    }

3.I do not use render section . For more information about RenderSection go asp.net mvc layouts and sections with razor

Upvotes: 1

Chris Pratt
Chris Pratt

Reputation: 239440

I've got a post on my blog that discusses some of this you might want to check out.

The layout code you're referencing doesn't make much sense. The only purpose to declaring an empty section, really, is to fulfill a requirement that it exists, when you don't want to actually pass anything there. Since the layout is what defines whether it must be present or not, it makes no sense for it to exist there, empty. More than that, if you implement a section in your base layout, you'll get a runtime error because there's no place higher in the view chain where it's defined.

Long and short, to provide a place holder in your layout for a section you use:

@RenderSection("SectionName", [true|false])

The boolean param indicates whether views that utilize this layout must implement the section; false means it's optional, while true means it's required.

To implement a section in a view, you use:

@section SectionName
{
    ...
}

If you have a layout that inherits from another layout, that layout must implement all required sections in the layout it inherits from. If you want the the section to be available to views that utilize the sub-layout, you must redefine the section in the section implementation:

_Layout.cshtml

@RenderSection("Foo", true)

_SubLayout.cshtml

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

@section Foo
{
    @RenderSection("Foo", true)
}

Finally, as to partial views vs. sections, it all comes down to whether you want to insert something into the layout or the view. For example, sections are most commonly used for inserting link tags to CSS files in the head or script tags before the closing body tag, where the view itself would not be able to touch directly. However, it's almost an apples and oranges comparison. Partials can be utilized in the layout, in the view, or even in a section. Whereas, sections can only be utilized in the layout.

Upvotes: 0

mehmet mecek
mehmet mecek

Reputation: 2685

Seems like layout is not put in Stuff1Link.cshtml

Can you put it like,

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

Upvotes: 1

Related Questions