My main motivation for trying to do this is to get Javascript that is only required by a partial at the bottom of the page with the rest of the Javascript and not in the middle of the page where the partial is rendered.
Here's a simplified example of what I'm trying to do:
Here is the layout with a Scripts section right before the body.
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
</head>
<body>
@RenderBody()
<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
@RenderSection("Scripts", false)
</body>
</html>
Here's an example view using this layout.
<h2>This is the view</h2>
@{Html.RenderPartial("_Partial");}
@section Scripts {
<script type="text/javascript">
alert("I'm a view.");
</script>
}
And here's the partial being rendered from the view.
<p>This is the partial.</p>
@* this never makes it into the rendered page *@
@section Scripts {
<script type="text/javascript">
alert("I'm a partial.");
</script>
}
In this example, the markup specified in the view is placed into the section, but the markup from the partial is not. Is it possible to populate a section from a partial view with Razor? If not, what are some other methods of getting Javascript that's only needed by partials at the bottom of the page without including it globally?
[Updated version] Updated version following @Necrocubus question to Include inline scripts.
My 2 cents, it is an old post, but still relevant, so here is an upgraded update of Mr Bell's solution which works with ASP.Net Core.
It allows adding scripts and styles to the main layout from imported partial views and subviews, and possibility to add options to script/style imports (like async defer etc):
The more elegant way to do this is to move partial view scripts into separate file and then render it in Scripts section of view:
The partial view _Partial.cshtml:
The partial view _PartialScripts.cshtml with scripts only:
This functionality is also implemented in ClientDependency.Core.Mvc.dll. It provides the html helpers: @Html.RequiresJs and @Html.RenderJsHere(). Nuget package: ClientDependency-Mvc
Here cames my solution to the frequently asked questions "how to inject sections from partial views to main views or main layout view for asp.net mvc?". If you do a search on stackoverflow by keywords "section + partial", you will get quite a big list of related questions, and given answers, but none of them are seems elegant to me by means of the razor engine grammar. So I just take a look to the Razor engine see if there could be a some better solution to this question.
Fortunately, I found something it is interesting to me of how the Razor engine does the compilation for the view template file (*.cshtml, *.vbhtml). (I will explain later), below is my code of the solution which I think is quite simple and elegant enough in usage.
usage: To use the code is quite simple as well, and it looks almost the same style to the usual. It also supports any levels to the nested partial views. ie. I have a view template chain: _ViewStart.cshtml->layout.cshtml->index.cshtml->[head.cshtml,foot.cshtml]->ad.cshtml.
In layout.cshtml, we have:
And in index.cshtml, we have:
And in head.cshtml, we would have the code:
it is the same in foot.cshtml or ad.cshtml, you can still define Head or Foot section in them, make sure to call @Html.EnsureSection() once at the end of the partial view file. That's all you need to do to get rid of the subjected issue in asp mvc.
I just share my code snippet so others may take use of it. If you feel it is useful, please don't hesitate to up rate my post. :)
Use
@using(Html.Delayed()){ ...your content... }
extensions from answer https://stackoverflow.com/a/18790222/1037948 to render any content (scripts or just HTML) later in the page. InternalQueue
should ensure correct ordering.You could have a second partial that is only in charge of injecting the necessary javascript. Place several scripts in there around
@if
blocks, if you want:This could obviously be cleaned up a bit, but then, in the
Scripts
section of your view:Again, it might not win a beauty prize but it will work.