How can I render section in a children Partial view? - asp.net-core

The runtime&SDK I am using is the newest version .net 6
Here are three Partial views in _Layout.cshtml of my project: header.cshtml/aside.cshtml/footer.cshtml .
Why I speared them to three parts for there are so many codes for them that I have to speare for coding convenient.
Now I need to add a section to the header.cshtml. Here is my code:
<header>
///some other codes
#RenderSection("ProductNav", required: false)
</header>
No matter there is a section "ProductNav", after the program ran, the page will all be blank without any error.
I found that it seems I can not use the RenderSection in a children Partial view.
It seems there is another way by using the Html.Partial to achieve this.
However, it needs to convert the views that I want to add to string. That's so troublesome.
Is there an easy way can achieve this? Thank you.

You want to show navbar on partial pages, You use partial view to achieve this function, But user can't add css style in partial view directly.
My idea is you can create a External CSS file in wwwroot and use it in page whitch needs to load partial view.
I write a demo to demonstrate the feasibility of this idea.
Views/Shared/_header.cshtml
<h2>This is head Partial View H2</h2>
<p>This is head Partial View P</p>
wwwroot/css/header.css
h2 {
color: blue;
}
p {
color: red;
}
views/Shared/_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - EmptyNEt5MVc</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
//add the css file in here
#await RenderSectionAsync("Css", required: false)
</head>
//.........
View
#{
ViewData["Title"] = "Privacy Policy";
}
//use partial view
<partial name="_header" />
<h1>#ViewData["Title"]</h1>
<p1>Use this page to detail your site's privacy policy.</p1>
//reference css file
#section Css{
<link rel="stylesheet" href="~/css/header.css" />
}
Then you can see the `header partial view' load the css file successfully
=============================================
In fact, View Component is more suitable for navigation bar than Partial View, There is a document about View Component.

Related

Assigning external style sheet page to razor page in .core web application

As you all know, in all normal .net framework empty web site projects every asp page has a head section in which we specify the external style sheet of that asp page. But I am shifting to .core web application project where pages do not have a head section. There is a head section in shared _layout but I do not want to use it because, as far as I know, the link for style sheet is shared across all pages what I shall do.
#page
#model IndexModel
#{
ViewData["Title"] = "Home page";
}
To achieve your requirement of adding references to external stylesheets inside the <head> section of page from view page(s), you can try following approach.
In _Layout.cshtml, calling RenderSection to optionally reference Styles section in the section, like below.
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - WebApplication1</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
#RenderSection("Styles", required: false)
</head>
Then you can add reference to the external style sheet file like below in view page.
#section Styles{
<link href="#Url.Content("~/Styles/mystyle.css")" rel="stylesheet" type="text/css" />
}
Test Result
till now the easiest solution i found
(1)- prevent your page from taking style from default shared (_layout.)
by writing the following code at your page
(2)- your razor page like any other html page can accept head section tag
and can accept tag even if it is not placed in head section
so refer to your external style sheet as u normally do
write following link tag at your razor page without head section
(1)
#{
Layout = "";}
<link rel="stylesheet" href="~/css/style.css" />

why RenderPage is not recognized?

This is discouraging me - I'm using the latest version of .NET core, SDK, visual studio 2019,
Started new project - ASP.net core Razor pages, I'm tring to add #RenderPage("") without success.
It looks like it is not part of abstract class RazorPage (that inherit RazorPageBase, at the Microsoft.AspNetCore.Mvc.Razor namespace (part of dotnet\packs\Microsoft.AspNetCore.App.Ref\3.1.3\ref\netcoreapp3.1\Microsoft.AspNetCore.Mvc.Razor.dll))
Everything I try, there is an error that says:
Error CS0103 The name 'RenderPage' does not exist in the current context
my _Layout page looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - TestApp</title>
#*<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />*#
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<div>
#RenderPage("/Shared/_MenubarPage")
</div>
<div class="container">
<main role="main" class="pb-3">
#RenderBody()
</main>
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
#RenderSection("Scripts", required: false)
</body>
</html>
(Of course I have partial _MenubarPage.cshtml page within Shared folder)
Can anyone please tell me where am I doing wrong? Should I add some kind of an external nuget?
Try the following code snippet in (the asp.net core 3.1) _layout page.
<partial name="_MenubarPage" />
You can use #RenderPage("_MenubarPage.cshtml");.
You can also use #RenderPage("_MenuPage.cshtml", MyModel) which allows you to supply any model you like to the view by including it as a second parameter.
You can also use #{Html.RenderPartial("_MenubarPage");} if you are using a partial. But don't forget that you need to wrap it with the razor code block #{}

where should i place the js script files in a mvc application so jquery works well?

the _layout.cshtml has code lines
#Scripts.Render("~/bundles/jquery")
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
by default they are placed inside the <body> tags by MVC. But when i leave them in this place some times jquery does not work. so i have decided to put those three lines in the <head> block in _layout.cshtml so the page will put styles and script files in the <head> as anyone would do with php or jsp. Good thing is when i put those files in <head> all my jquery started working again. But most MVC books says to place the scripts in the <body> block.
So where should i put them?
updated post:
here is my bundle file:
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
"~/Scripts/jquery-ui-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
}
here is the layout file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/css")
</head>
<body>
#RenderBody()
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryui")
#Scripts.Render("~/bundles/modernizr")
#RenderSection("scripts", required: false)
</body>
</html>
Here is the view:
#{
ViewBag.Title = "TestPage";
}
<h2>TestPage</h2>
<input type="submit" name="name" value="Click me" id="btn"/>
<div id="d1"></div>
<script type="text/javascript">
$('#btn').click(function(){
alert('clicked');
});
</script>
here is teh video to show that click does not work
In your layout file, the script tag to load jQuery library is included at the end of the page. But there is another section called scripts below that. So in your individual pages ( Ex : Index,View etc..) You should be putting your javascript inside the section scripts
<body>
#RenderBody()
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
</body>
And in your views (Ex : Index view)
#section scripts{
<script src="~/Scripts/SomePageSpecificFile.js"></script>
<script>
$(function(){
// Your other js code goes here
});
</script>
}
So when razor render the page it will be
<body>
<script src="/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/SomePageSpecificFile.js"></script>
<script>
$(function(){
// Your other js code goes here
});
</script>
</body>
As long as you execute your page specific javascript which uses jQuery inside the scripts section ,you should be fine.

Add css, js or other content to a views head from partial views

I have found a few questions relating to this, but generally there are many different answers and they all seem very messy and complex.
If that is what needs to be done, then ok i better sit down and tackle it.
I want to know what the simplest and most efficient way is to add content to your head from partial views.
Reason I need to do this is i need certain java script and jquery on each page and it differs from page to page. I donot just want to add them all in the _layout view.
You can do this with sections. For example:
I have more than two view which each other has same _Layout.My Index action in Company Controller has a sections as follow:
#model Invoice.Model.HelperClasses.CompanyViewModel
#{
ViewBag.Title = "Companies";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section usage{
<link href="~/css/uniform.default.css" rel="stylesheet" />
}
#section other{
<link href="~/css/datepicker.css" rel="stylesheet" />
<link href="~/css/SimpleSlide.css" rel="stylesheet" />
<link href="~/css/responsive-tables.css" rel="stylesheet" />
}
#section script
{
<script src="~/js/datepicker/bootstrap-datepicker.js"></script>
}
and Display Action in Invoice controller has same sections but different css and js as follow:
#model Invoice.Model.HelperClasses.InvoiceViewModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section usage{
#*<link href="~/css/uniform.default.css" rel="stylesheet" />*#
}
#section other{
<link href="~/css/DT_bootstrap.css" rel="stylesheet" />
<link href="~/css/responsive-tables.css" rel="stylesheet" />
<script src="~/js/datatables/extras/ZeroClipboard.js"></script>
}
#section script
{
<script src="~/js/datepicker/bootstrap-datepicker.js"></script>
<script src="~/js/validate/jquery.metadata.js"></script>
<script src="~/js/validate/jquery.validate.js"></script>
}
and then you can use this section in _Layout but its required argument should be false. Look at:
<!DOCTYPE html>
<html>
<head>
<!--usage-->
#RenderSection("usage", required: false)
<!--other-->
#RenderSection("other", required: false)
<!--script-->
#RenderSection("script", required: false)
<head>
<body>
</body>
</html>
On your _Layout.cshtml page (Or any other master page) Use following code on inside of <head></head> tag.
#if (IsSectionDefined("SpecialOther"))
{
#RenderSection("SpecialOther")
}
On the page that you want special css,script or any other item, specify their refernces. e.g.,
#section SpecialOther{
<link href="~/css/responsive-tables.css" rel="stylesheet" />
<script src="~/js/datatables/extras/ZeroClipboard.js"></script>
}

Use controller result from other mvc project within solution

I've got a new solution that contains several project 'groups'. Each group contains a Cloud Project, a Web Role Project and a Test Project. All Web Role Projects are MVC4.
One of the Web Roles is the entry point for the visitor. Parts of what the visitor will see, should come from the other Web Roles from within the solution. I cannot get it working and after spending several hours googling, I still cannot solve it. Maybe anyone can be helpful on this issue.
For example, I need to fill the header content with data that I can get from one of the other Web Roles. Let's call that controller HeaderController. The controller in the main project (HomeController) looks like this:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
//var headerController = new Generic.HeaderFooterContainer.Controllers.HeaderController();
//var foo = headerController.Index().ExecuteResult();
//ViewBag.Header = headerController.;
return View();
}
In the comments are some things I've tried to debug some things.
Here's the page layout of the main project. The body is still empty, as this problem is just about the page header which could be placed as html from the ViewBag or ViewData or even with an own #section.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="headerHolder">
<div class="innertube">
<div id="header">
#ViewBag.Header
</div>
</div>
</div>
<div class="contentHolder">
<div class="innertube">
<div id="content">
#RenderBody()
</div>
</div>
</div>
<div class="footerHolder">
<div class="innertube">
<div id="footer">
</div>
</div>
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bms")
#RenderSection("scripts", required: false)
</body>
</html>
The problem I face is that I just can't find out how I should make this work. How do I get the data in the header? A few things I've noticed are:
If I run the HeaderFooterContainer project in its dedicated solution, it works alright (I can get /Header and get the expected response displayed in the browser window)
If I run the Main project, I can see the home page, but if I ask for /Header, it can find the controller, but not the view. It's probably looking for the view in the main project although it is located in the HeaderFooterContainer project.