How to use @section scripts in a partial view MVC.Core

Iva*_*res 5 c# asp.net-mvc .net-core asp.net-core

In ASP.NET Core MVC it is possible to define a script section for a page like this:

@section scripts {
    <script>
        alert('hello');
    </script>
}
Run Code Online (Sandbox Code Playgroud)

And if the the layout contains :

@RenderSection("Scripts", required: false)
Run Code Online (Sandbox Code Playgroud)

your script(s) will be rendered. This come in handy per example to guarantee that the scripts will be rendered after all javascript includes like jQuery.

But how to render a script in a partial view?

Iva*_*res 10

Here is a solution :

In Layout page :

@Html.PageScripts()
Run Code Online (Sandbox Code Playgroud)

In the Partial :

@using (Html.BeginScripts())
{
 <script>
   alert('hello');
 </script>
}
Run Code Online (Sandbox Code Playgroud)

And The Helper Class for MVC.core

using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.IO;

namespace MyProjectNamespace
{
    public static class HtmlHelpers
    {
        private const string ScriptsKey = "DelayedScripts";

        public static IDisposable BeginScripts(this IHtmlHelper helper)
        {
            return new ScriptBlock(helper.ViewContext);
        }

        public static HtmlString PageScripts(this IHtmlHelper helper)
        {
            return new HtmlString(string.Join(Environment.NewLine, GetPageScriptsList(helper.ViewContext.HttpContext)));
        }

        private static List<string> GetPageScriptsList(HttpContext httpContext)
        {
            var pageScripts = (List<string>)httpContext.Items[ScriptsKey];
            if (pageScripts == null)
            {
                pageScripts = new List<string>();
                httpContext.Items[ScriptsKey] = pageScripts;
            }
            return pageScripts;
        }

        private class ScriptBlock : IDisposable
        {
            private readonly TextWriter _originalWriter;
            private readonly StringWriter _scriptsWriter;

            private readonly ViewContext _viewContext;

            public ScriptBlock(ViewContext viewContext)
            {
                _viewContext = viewContext;
                _originalWriter = _viewContext.Writer;
                _viewContext.Writer = _scriptsWriter = new StringWriter();
            }

            public void Dispose()
            {
                _viewContext.Writer = _originalWriter;
                var pageScripts = GetPageScriptsList(_viewContext.HttpContext);
                pageScripts.Add(_scriptsWriter.ToString());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Tip: import you class helper in _ViewImports.cshtml so you can use it in all views.

  • 只是想说谢谢你,我出于开发目的从这段代码中制作了一个非常优雅的解决方案:) (2认同)