Search code examples
c#razorrazor-pagesrazorengine

My solution to mapping CSS styles to Razor Pages is probably convoluted


I could've sworn there was once a time where the razor engine would automatically apply PageName.cshtml.css style to the PageName.cshtml razor page. I don't know what configuration I was running during the time, but that just doesn't seem to be the case for me now, so I eventually keeled and opted edit the _ViewStart.cshtml file as follows:

@{
    string? Path = Context.GetRouteData().Values.First().Value?.ToString();
    string jsFile = $"{Path}.cshtml.js";
    string cssFile = $"{Path}.cshtml.css";
}

<script src="@jsFile"></script>
<link rel="stylesheet" href="@cssFile" />

When the link tag would resolve to ".cshtml.css", it would search only in wwwroot, configured the code as follows in this repo: https://github.com/TerminalZero/Razor-Better-Static-File-Serving

It contains a fluent API for serving specific file extensions at specific directories:

app.UseStaticFiles(new FileExtensionDirectoryMappings()
    .AddDirectory("/wwwroot").ServingFileTypes() // Empty makes directory serve all file types.
    .AddDirectory("/Pages").ServingFileTypes(".css", ".js")
);

But, I am doubtful that all this was necessary. Was there a less convoluted setup for this functionality?


Solution

  • The name-based styling behavior is observed with the inclusion this line of code:

    app.UseStaticFiles();
    

    as well as this line of markup:

    <link href="<ProjectName>.styles.css" rel="stylesheet" />
    

    Razor then combines all the <PageName>.cshtml.css and <PageName>.razor.css stylesheets into the aforementioned file, with modifications to the selectors to target a randomly generated attribute to the style the corresponding auto-generated attributes on elements within a page; as to prevent one page's styles from overriding another's.

    You'll find this setup is works consistently in Blazor apps, but not in Razor apps. This is because the razor and mvc templates currently replace the space in your project name with an underscore. UseStaticFiles still serves the file based on the exact name of your project, whitespace included.