Search code examples
c#typescriptrazor-pagesasp.net-core-6.0

Loading js files for each page dynamically using _ViewStart in ASP.NET Core 6


I'm working on a project using ASP.NET Core 6 Razor pages.

The *.ts files located in the Script directory and compiler will put the output in wwwroot/js/.

My goal is to load each of these .js files for pages with the same name, for example if my page name is index.cshtml, it should load the index.js file automatically.

So far I've done this in my _ViewStart.cshtml:

var pageName = System.IO.Path.GetFileNameWithoutExtension(Path);
var jsFile = "~/js/" + pageName + ".js";
//some how load the jsFile

but the problem is that the jsFile is always "_ViewStart", I need some how get the name of the file that is using _ViewStart at the moment (like if index.cshtml is loading for user and it's rendering _ViewStart, I need to get the index.cshtml) and viewbags are really bad, they are easy to forget and mess with typos, I need something safer.

I think I can achieve the same using reflection in my application startup (appending the <script> at the bottom of each *.cshtml file maybe?), but it's a bit nasty, I guess.

Sorry if this is a long or bad question


Solution

  • You can get the current page's file name from the Endpoint data for the current page. For example, in _Layout.cshtml, you can do the following:

    @using Microsoft.AspNetCore.Mvc.RazorPages;
    @inject IWebHostEnvironment environment
    @{
        var endpoint = Context.GetEndpoint() as RouteEndpoint;
        var jsFile = endpoint?.Metadata.OfType<PageActionDescriptor>().FirstOrDefault()?.ViewEnginePath.Trim('/');
        var fileExists = jsFile is not null ? File.Exists(System.IO.Path.Combine(environment.WebRootPath, "js", jsFile + ".js")) : false;
    }
    

    Then, at the point you want to inject the script:

    @if(fileExists)
    {
        <script src="~/js/@(jsFile).js"></script>
    }