Home > database >  How to get an ASP.NET Core MVC view to refer to a script section in another file?
How to get an ASP.NET Core MVC view to refer to a script section in another file?

Time:07-25

I'm facing an issue when I'm trying to link my .cshtml file and my JavaScript reference in an ASP.NET Core 6 MVC.

As of right now, I have made a webpack setup such that it generates my JavaScript tags in a separate file called home.sources.cshtml:

@section Scripts
{
    <script src="/js/npm.popperjs.bundle.js"></script>
    <script src="/js/npm.jquery.bundle.js"></script>
    <script src="/js/npm.bootstrap.bundle.js"></script>
    <script src="/js/home.bundle.js"></script>
}

As you can see, my tags are encapsulated in the Scripts section. All these dependencies are for my View/Home/Index.cshtml page:

@{
    ViewData["Title"] = "Home Page";
}

<div >
    <h1 >Welcome</h1>
    <p >Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

// Insert Script Section here

I want to make it so that the contents of home.sources.cshtml gets appended to this page at runtime. I don't want to manually add the script section myself, nor do I want to modify the page later on should I add more JavaScript dependencies. Any extra JavaScript dependencies that I add or remove will have their changes reflected only in home.sources.cshtml.

How do I go about doing that?

I was looking into @Html.Partial() in the attempt to add the Script section into the page as a partial view, but that doesn't seem to work.

CodePudding user response:

That's a very odd way to add script references if I understand what you're doing here.

Normally in MVC You see a couple lines in the layout page that look like this:

    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")

Those refer to a set of bundles in App_Start -> BundleConfig.cs

That's the standard way of adding .js files to your runtime pages.

CodePudding user response:

Thank you Jonespopolis for giving me this approach.

Essentially, what I need to do is to make a Layout template file, specifying that I am using my preexisting Layout file that I was already using, and declaring where all the JS tags would go. For instance, here's my template file:

@{
    Layout = "_Layout";
}

@RenderBody()

@section Scripts
{
    <% for (index in htmlWebpackPlugin.files.js) { %>
    <script src="<%= htmlWebpackPlugin.files.js[index] %>"></script>
    <% } %>
}

This template file refers back to my original _Layout.cshtml file:

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Head content here -->
</head>
<body>
    <!-- Header content here -->

    <div >
        <main role="main" >
            @RenderBody()
        </main>
    </div>

    <!-- Footer content here -->
</footer>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

The @await RenderSectionAsync("Scripts", required: false) line will render the Script section that I created in my template file.

From there, I used Webpack's Htmlwebpackplugin with the following config:

plugins: [
        new HtmlWebpackPlugin({
            inject: false,
            template: 'Views/Shared/PageTemplate.cshtml',
            filename: '../../Views/Shared/home.sources.cshtml',
            minify: false
        }),
    ],

Running the webpack command will net us a home.source.cshtml file containing everything in the template file, but it shows my actual JS references needed for home.cshtml. All that's left is to make this file be the Layout for the page, by inserting this at the beginning:

@{
    Layout = "home.sources";
}

Running the application gives me the home page with all the correct JS tags downloaded! Now if I ever change my JS dependencies, I don't need to ever worry about generating the tags nor inserting them into the page, since all of that has been automated now, which is exactly what I wanted!

  • Related