MVC - Nested Partial Views - c#

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().

Related

How to fix 'AspNetCore.Views_Home_Index.ExecuteAsync()' NullReference error in MVC

I'm setting up a simple ASP.NET Core MVC project that includes some partial views that I want to be rendered asynchronously. But it seems that, regardless whether they are rendered asynchronously or not I keep getting the same ExecuteAsync() NullReferenceException error.
I have checked all the models and the HTML code but it doesn't seem to work either way, always returning:
An unhandled exception occurred while processing the request.
NullReferenceException: Object reference not set to an instance of an
object. AspNetCore.Views_Home_Index.ExecuteAsync() in Index.cshtml,
line 4.
Index.cshtml:
#using BestDeal.ViewModels
#model HomeViewModel
#await Html.PartialAsync("ArtikalCarouselPocetna")
<h2>Istaknuti artikli</h2>
<div class="row">
#foreach (var artikal in Model.odabraniArtikli)
{
#Html.Partial("ArtikalPregled", artikal)
}
</div>
ArtikalCarouselPocetna partial view:
<div class="row carousel-holder marginTop1">
<div class="col-md-12">
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
<li data-target="#carousel-example-generic" data-slide-to="2"></li>
</ol>
<div class="carousel-inner">
<div class="item active">
<img class="slide-image" src="https://images-na.ssl-images-amazon.com/images/I/71t-J3VJtEL._SX425_.jpg" alt="">
</div>
<div class="item">
<img class="slide-image" src="https://zdnet1.cbsistatic.com/hub/i/r/2019/04/17/1f68c3a6-495e-4325-bc16-cc531812f0ec/thumbnail/770x433/84ff4194826e8303efb771cd377a854f/chuwi-herobook-header.jpg" alt="">
</div>
<div class="item">
<img class="slide-image" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRKRl7BqXfZupIBH4N8i-tD45gVPctFV5jKTeTmOIADFhZ8J_DAYQ" alt="">
</div>
</div>
<a class="left carousel-control" href="#carousel-example-generic" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</div>
</div>
</div>
Your error in, I think you model is null. So you can check it like this
if(model != null) then
#foreach (var artikal in Model.odabraniArtikli)
{
#Html.Partial("ArtikalPregled", artikal)
}
So, I see you view located in different folder, it's mean you need point full path
#await Html.PartialAsync("~/Views/Shered/ArtikalCarouselPocetna.cshtml")
but I suggest you better use
#{
await Html.RenderPartialAsync("~/Views/Shered/ArtikalCarouselPocetna.cshtml");
}
Alternatively, you can render a partial view with RenderPartialAsync. This method doesn't return an IHtmlContent. It streams the rendered output directly to the response. Because the method doesn't return a result, it must be called within a Razor code block:
#{
await Html.RenderPartialAsync("_AuthorPartial");
}
Since RenderPartialAsync streams rendered content, it provides better performance in some scenarios. In performance-critical situations, benchmark the page using both approaches and use the approach that generates a faster response.
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-2.2
Also
I advise you use partial view with _ https://stackoverflow.com/a/10321458/8006943

Use HtmlHelper in Kendo Template

What I'm trying to do seems pretty simple but I'm not sure if it's possible or not.
I have a Kendo Template and I am wanting to use an HtmlHelper that I created inside of it but I'm having an issue with passing the value into it.
This is what my template looks like:
<script type="text/x-kendo-tmpl" id="reviewTemplate">
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">
#:ProducerProfileDisplay#
</div>
</div>
<div class="panel-body">
#Html.Raw(Html.DisplayRating(#:Rating#))
<p>#:ReviewText#</p>
</div>
</div>
</script>
The problem with this is it just doesn't like the syntax at all and I can't compile my project. And if I decide to put it inside of quotes then it will literally just pass in the string #:Rating#.
By the way, the method I created is expecting a double.
Any ideas?

Controller method for shared layout view in MVC?

Question background:
I have a MVC site that implements BootStrap. Currently each page is based on a MasterLayout view page. This master contains a dropdown list that will be populated with the cart items in the sites shopping cart along with the carts total monetary value. Please note currently the details in the dropdown are fixed values in the HTML:
What I'm after:
I've tried searching for this but cant seem to find exactly the answer. I want to be able to populate the dropdown in the navbar with the cart contents each time a page is loaded. To do this I need a method to extract the cart item objects which are stored in a SESSION object variable. Currently my MasterLayout view is just that, its a view that has no controller associated with it.
How do I go about assigning some sort of method to my MasterLayout so I can pass the cart items model to the view which in-turn will be set to the dropdown each time the page is loaded?.
Here's the HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
#Styles.Render("~/Content/bootstrap.css")
#Styles.Render("~/Content/Styles.css")
#Scripts.Render("~/bundles/modernizr")</script>
</head>
<body>
<div class="navbar navbar-fixed-top">
<nav class="navbar navbar-default" role="navigation" id="nav">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand logo">HS<b>WH</b></a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li>Products</li>
<li>About Us</li>
<li>Contact</li>
</ul>
<form class="navbar-form pull-right">
<input type="text" class="form-control" placeholder="Search this site..." id="searchInput">
<button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
</form>
<form class="navbar-form pull-right">
<div class="btn-group btn-group-cart">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="pull-left"><i class="fa fa-shopping-cart icon-cart"></i></span>
<span class="pull-left">Shopping Cart: 2 item(s)</span>
<span class="pull-right"><i class="fa fa-caret-down"></i></span>
</button>
<ul class="dropdown-menu cart-content" role="menu">
<li>
<a href="detail.html">
<b>Penn State College T-Shirt</b>
<span>x1 $528.96</span>
</a>
</li>
<li>
<a href="detail.html">
<b>Live Nation ACDC Gray T-Shirt</b>
<span>x1 $428.96</span>
</a>
</li>
<li class="divider"></li>
<li>Total: $957.92</li>
</ul>
</div>
</form>
</div>
</div>
</nav>
</div>
#RenderBody()
<footer>
<div class="container">
<div class="row">
<div class="col-sm-12 textAlignCenter">
<h5>Copyright © 2014 - Test Site</h5>
</div>
</div>
</div>
</footer>
<script>
$(document).ready(function () {
$('.dropdown-toggle').dropdown('toggle')
});
</script>
</body>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
</html>
I would probably do this using a child action invoked from the master layout.
#Html.Action("Cart")
On server side create action returns PartialViewResult, which render your cart model.
At front-end render your partial via #Html.Action("YourPartialCart",'CartController') or ajax call.
All Views have a controller associated with them because the views are inherits. E.g. when you create a view you set it's Layout to be equal to the master.cshtml file.
Your view has a Model associated with it.
You can tackle this a couple of ways.
The simplest would be to use something like HttpContext.Current.Items, which is a request unique collection of shared data accessible from anywhere during an HttpRequest.
The next would be to use inheritance on your models. For example, Create Models like this
MasterModel
-> CartPageModel (inherits MasterModel)
-> AccountSettingsModel (inherits MasterModel)
etc.
Then on your master page set the model to MasterModel via the #Model MasterModel code, and on your view it would be #Model CartPageModel.
In your controller the code will populate values on the base model MasterModel and it's derrived type CartPageModel.

C#/MVC Wrap View with Partial?

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>

Nested layouts for MVC5

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.

Categories

Resources