Please, I need a way to master Blazor multi-layered layouts, but for now, I desperately need to know how to null layouts so that I can add everything from `
<html>
to
</html>
`
myself on the #page directly.
Why do I want to do this?
in MVC I can make the ViewModel inherit from the _layout ViewModel so that I can dynamically add user images, name, properties... in the navigation and side-nav, even hide some nav options. like in the picture below.
Looks like you want to custom your MainLayout?
You can just clear it, open MainLayout.razor (where the _Layout lies) and only add #Body in it:
#inherits LayoutComponentBase
#Body
From your example, seems you just want to custom your NavMenu?
It's the same,open NavMenu.razor and just modify the navs.
And for extension, if you want to different types of Layout, you can use NavigationManager to
check the parameter in your url and it will use the related Layout, like:
#inherits LayoutComponentBase
#inject NavigationManager _navManager
#if (_navManager.Uri.Contains("CustomLayout1"))
{
#Body
}
else
{
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4">
About
</div>
<div class="content px-4">
#Body
</div>
</div>
</div>
}
So if the page is #page "/CustomLayout1/counter" Then it will use your null MainLayout in this demo.
I think you want multiple layouts.
The base file (_Host.cshtml for blazor server side or index.html for WASM), needs to be as empty as possible to only have and
For _Host.cshtml, you probably need to do something like:
#page "/"
#namespace YOURNAMESPACE.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#{
Layout = null;
}
<html>
<component type="typeof(App)" render-mode="ServerPrerendered" />
</html>
For index.html, something like:
You can read more here: https://learn.microsoft.com/en-us/aspnet/core/blazor/layouts?view=aspnetcore-5.0
Related
Im using ASP.NET Core 2.2. The problem that I have is I don't know where to use
#RenderBody() in my _Layout page. This is representation of what I want to do:
The green parts should come from _Layout and white parts coming from HomePage.cshtml. My HomePage consists of two parts a slider and a list of content below it.This is what I tried, but it doesn't meet my need because i can't put slider in it.
this is _Layout
<html>
<body>
<main>
<header></header>
<div class="left-col">
<div class="content">#RenderBody()</div>
<div class="right-col">
<footer></footer>
</main>
</body>
</html>
You can define a section in the layout to render the desired content
HomePage.cshtml
#{
ViewBag.Title = "Home Page";
}
#section Slider {
<div>My HomePage slider</div>
}
<p>My HomePage content</p>
The layout would check to see if the section exists and render it if it does
_Layout.cshtml
<html>
<body>
<main>
<header></header>
#if (IsSectionDefined("Slider")) {
<div class="homepage-slider">
#RenderSection("Slider", required: false)
</div>
}
<div class="left-col">
<div class="content">#RenderBody()</div>
<div class="right-col">
<footer></footer>
</main>
</body>
</html>
You would obviously have to specify what ever styling needed to position the section where desired.
Reference Layout in ASP.NET Core: Sections
I am getting an error ("Server Error in '/' Application") when I nest partial views in my MVC app. The views work fine individually, but not when nested. It's my understanding that it's okay to do this, so what am I doing wrong?
Essentially, I am trying to use partials as sub-layouts within my _Layout.cshtml.
Here's my main layout - _Layout.cshtml
<!DOCTYPE html>
<html>
<head>...</head>
<body style="padding-top: 80px;">
<div class="container-fluid">
<div class="row">
<div id="myTab" class="col-lg-12 col-md-12 col-sm-12">
...
<div class="tab-content">
<div class="tab-pane fade" id="search">
#Html.Partial("~/Areas/Search/Views/Shared/_SearchLayout.cshtml")
</div>
</div>
</div>
</div>
</div>
#RenderBody()
#RenderSection("scripts", required: false)
</body>
</html>
This is the first partial view (_SearchLayout). If I remove the partials AND #RenderBody, no error.
<div class="container-fluid">
#Html.Partial("_PolicySearch")
#Html.Partial("_ClaimSearch")
</div>
#RenderBody()
This partial view is nested in the first partial view (_SearchLayout):
<div class="row top-buffer search-outline form-horizontal">
<div class="col-md-1 search-icon-size text-primary">
<i class="glyphicon glyphicon-heart"></i>
</div>
<div class="col-md-1 search-icon-size text-primary">
<h4>Claim Search</h4>
</div>
</div>
In your first partial view:
Remove RenderBody
Replace Html.Partial to Html.RenderPartial
I also would recommend to rename your partial view to something not containing the word "Layout" to avoid the mismatch between the view types.
Use Html.RenderPartial instead
The problem is #RenderBody(). This can only be called in a layout, which when used in this way _SearchLayout.cshtml is not, despite its name.
The important thing to remember about layouts, partials and views in ASP.NET MVC is that they're all views. The only thing that differentiates them is how they're used. In this instance, you're using the _SearchLayout.cshtml view as a partial, and partials can't use #RenderBody().
Is it possible to wrap a view with a partial file? Sort of like a layout, but with a partial?
For example:
Layout
<html>
...
<body>
<div>#RenderBody</div>
</body>
</html>
View
#{
Layout = "~/Views/Shared/_PartialWrapper.cshtml";
}
<!--content I want to wrap with partial-->
<div class='alert alert-info'>HELLO WORLD</div>
Partial
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div style='border:1px solid #cccccc;'>
<div style='background-color:black;color:white;'>
StackOverflow Rocks
</div>
<div>
#RenderBody
</div>
</div>
When I tried the above scenario, I get an error on the partial file on the "#RenderBody" line. The error:
The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments
Is there a better way to do this -- or make the above work?
As #Overmachine mentioned, RenderBody is a Method so you need to write #RenderBody() like so:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div style='border:1px solid #cccccc;'>
<div style='background-color:black;color:white;'>
StackOverflow Rocks
</div>
<div>
#RenderBody()
</div>
</div>
I've seen a few posts on this topic:
Razor Nested Layouts with Cascading Sections
MVC 3 - Nested layouts - sections don't render in Areas
And it always seems to be problematic. However they are both pretty old so wondering if things have changed.
Basically I have a master layout, and 3 different body templates based on what kind of page it is. For examples sake:
_Layout.cshtml
<html lang="en">
<head>
</head>
<body style="padding: 50px 0;">
<header class="navbar navbar-default navbar-fixed-top" role="banner">
#Html.Partial("_MenuPartial")
</header>
<ol class="breadcrumbs">
#RenderSection("breadcrumbs", true);
</ol>
<section>
#RenderBody();
</section>
<footer class="navbar navbar-default navbar-fixed-bottom">
#Html.Partial("_FooterPartial")
</footer>
#Html.Partial("_ScriptInitPartial")
</body>
</html>
_LayoutForEdit.cshtml
<div class="panel panel-primary">
<div class="panel-body">
<div class="col-lg-2">
<ul class="nav nav-pills nav-stacked">
#RenderSection("tabs", true)
</ul>
</div>
<div class="col-lg-10">
<div class="tab-content">
#RenderBody()
</div>
</div>
</div>
<div class="panel-footer">
<button class="btn btn-primary" data-bind="enable: Entity.isValid, click: save">Save</button>
</div>
</div>
Now this renders fine when called. Almost.
The rendering of sections must be in the child layout it seems. If I try to put the breadcrumbs in the _Layout.cshtml, it will fail because _LayoutForEdit.cshtml never rendered it. How can I fix this?
The following sections have been defined but have not been rendered for the layout page "~/Views/Shared/_LayoutForEdit.cshtml": "breadcrumbs".
I know it's an old question. I thought I'd share this anyway in case anyone else runs into this (like I did).
At the bottom of your child layout, you define a section with the same name as the section in the parent layout. Inside of this section you simply put a #RenderSection, again specifying the same name as before. Once this is in place, you essentially have the child layout "bypass" content from pages, up to its parent layout:
#section breadcrumbs {
#RenderSection("breadcrumbs", true)
}
Not sure if you still need help, but I'll answer anyways.
There RenderSection method takes the following parameters according to the
MSDN Documentation:
public HelperResult RenderSection(
string name,
bool required
)
Parameters
name
Type: System.String
The section to render.
required
Type: System.Boolean
true to specify that the section is required; otherwise, false.
Change the call to:
#RenderSection("breadcrumbs", false);
If the section "required" parameter is false, it will not give an error if that section is not included by a view.
I've created a section for a footer in my asp.net MVC 3 Web Application:
<footer>
#RenderSection("Footer", true)
</footer>
This footer will be the same on every page, so it doesn't make sense for me to define it for each and every view. So, is there any way I can globally declare this footer section for all views? The footer will contain code so as far as I know it's bad practice, if not impossible, to directly define it in the .cshtml file.
Thank you in advance.
I have handled the same scenario by creating a partial view "_Footer" and place it on the "_Layout".
#ViewBag.Title
#Html.Partial("_Header")
<div id="content">
<div id="nav-bar">
#Html.Partial("_Menu")
</div>
<div class="container">
#RenderBody()
</div>
</div>
<div id="footer">
#Html.Partial("_Footer")
</div>
#Html.Partial("_Scripts")
Sure:
<footer>
#if (IsSectionDefined("footer"))
{
#RenderSection("footer")
}
else
{
... put your default footer here
}
</footer>
And in views that you want to override the footer simply define the section.
You can place the footer in your SiteLayout.cshtml. See this article for more information on using layouts with MVC 3.