Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Razor Section multiple times in a View & PartialView (merge) without overriding it?

In the _Layout.cshtml file, I have a section at the bottom of the body called "ScriptsContent" declared like this:

@RenderSection("ScriptsContent", required: false) 

In my view, I can then use this section to add scripts to be executed. But what if I also have a PartialView that also need to use this section to add additional scripts?

View

@section ScriptsContent {     <script type="text/javascript">         alert(1);     </script> }  @Html.Partial("PartialView") 

PartialView

@section ScriptsContent {     <script type="text/javascript">         alert(2);     </script> } 

Result

Only the first script is rendered. The second script doesn't exist in source code of the webpage.

Razor seems to only output the first @section ScriptsContent that it sees. What I would like to know is if there's a way to merge each call to the section.

If we cannot do this, what do you propose?

like image 669
Alexandre Jobin Avatar asked Aug 16 '11 15:08

Alexandre Jobin


2 Answers

Here's a solution for that problem. It's from this blog: http://blog.logrythmik.com/post/A-Script-Block-Templated-Delegate-for-Inline-Scripts-in-Razor-Partials.aspx

public static class ViewPageExtensions {             private const string SCRIPTBLOCK_BUILDER = "ScriptBlockBuilder";      public static MvcHtmlString ScriptBlock(this WebViewPage webPage, Func<dynamic, HelperResult> template)     {         if (!webPage.IsAjax)         {             var scriptBuilder = webPage.Context.Items[SCRIPTBLOCK_BUILDER] as StringBuilder ?? new StringBuilder();              scriptBuilder.Append(template(null).ToHtmlString());             webPage.Context.Items[SCRIPTBLOCK_BUILDER] = scriptBuilder;              return new MvcHtmlString(string.Empty);         }          return new MvcHtmlString(template(null).ToHtmlString());     }      public static MvcHtmlString WriteScriptBlocks(this WebViewPage webPage)     {         var scriptBuilder = webPage.Context.Items[SCRIPTBLOCK_BUILDER] as StringBuilder ?? new StringBuilder();          return new MvcHtmlString(scriptBuilder.ToString());     } } 

so anywwhere in your View or PartialView you can use this:

@this.ScriptBlock(     @<script type='text/javascript'>         alert(1);     </script> ) 

and in your _Layout or MasterView, use this:

@this.WriteScriptBlocks() 
like image 80
Alexandre Jobin Avatar answered Sep 29 '22 08:09

Alexandre Jobin


There is no way to share sections between a view and partial views.

Absent a ScriptManager-like solution, you could have a collection of script files (initialized in your view and stored either in HttpContext.Items or in ViewData) to which the partial view would append the script file names it requires. Then towards the end of your view you would declare a section that fetches that collection and emits the right script tags.

like image 22
marcind Avatar answered Sep 29 '22 09:09

marcind