0
votes

EDIT I found that my Login.cshtml actually references another layout page, called "_LayoutAccount.cshtml", which also has @RenderSection("Scripts", required: false) and also references Layout = "_Layout"; Everything else remains the same.

Chrome is throwing a "jquery.validate.js:15 Uncaught ReferenceError: jQuery is not defined" because my "_ValidationScriptsPartial" section is loaded before jQuery & other JS libraries defined in _Layout.cshtml.

"_ValidationScriptsPartial" is a referenced in Login.cshtml in a @Section Scripts.

Section "Scripts" are called in _Layout.cshtml (@RenderSection("scripts", required: false) after all my other scripts.

I've tried multiple combinations of ordering/calling scripts & sections, and googled and searched SO, butall similar problems had solutions which don't apply to me.

_Layout.cshtml:

... 
@RenderBody() 
...
    <environment include="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment exclude="Development">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                crossorigin="anonymous">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("Scripts", required: false)

Login.cshtml:

Layout = "_LayoutAccount";
...
@section Scripts {
  @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

ValidationScriptsPartial.cshtml

<environment include="Development">
    <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
    <script src="~/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js"></script>
</environment>
<environment exclude="Development">
    <script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js"
            asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
            asp-fallback-test="window.jQuery && window.jQuery.validator"
            crossorigin="anonymous">
    </script>
    <script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.9/jquery.validate.unobtrusive.min.js"
            asp-fallback-src="~/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"
            asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
            crossorigin="anonymous">
    </script>
</environment>

Finally, the scripts are loaded in the following order:

jquery.validate.js
jquery.validate.unobtrusive.js
jquery.js
bootstrap.js
site.js

AFAIK, this shouldn't be happening, my Section is being called at the wrong time.

1
Can you expand your _Layout.cshtml to also show where you are calling RenderSection? - poke
Sections names are case-sensitive, so @section Scripts won’t render at RenderSection("scripts"). Are you sure that’s how it looks? Is there another @RenderSection somewhere? Also, can you take a look at the rendered HTML in the browser (CTRL+U) to see in what order the script tags are rendered? - poke
@poke lowercase "scripts" was just something I tried, it doesn't work with both "scripts" or "Scripts". - A Horse From Belgrade
@poke the rendered html in the browser the script tags are rendered in the order I mentioned, validation scripts first, jquery scripts after. - A Horse From Belgrade
Did you make this error by calling Login.cshtml ?If you do not use Layout = "_LayoutAccount";,can other page render successfully? - Rena

1 Answers

0
votes

Due to you use Layout = "_LayoutAccount"; in Login.cshtml,so it would not load the component of _Layout.cshtml in Login.cshtml.You need to add jquery in _LayoutAccount.cshtml:

<environment include="Development">
    <script src="~/lib/jquery/dist/jquery.js"></script>
</environment>

UPDATE:

If you use nested Layout in _LayoutAccount,you need to call the RenderSection() inside a Section to change like below:

@{
    Layout = "_Layout";
}

design by yourself...
@section Scripts
{
    @RenderSection("scripts", required: false)
}

Reference: https://asp.net-hacker.rocks/2016/02/18/extending-razor-views.html