Can RCL Static Assets be overriden ?
# package-development
m
Should packages that deliver assets as
staticwebassets
in a
razor class library
support overriding the embedded static asset with a local physical file or is it just razor files that are supported? I did find https://learn.microsoft.com/en-us/aspnet/core/razor-pages/ui-class?view=aspnetcore-8.0&tabs=visual-studio#override-views-partial-views-and-pages
Copy code
When a view, partial view, or Razor Page is found in both the web app and the RCL, the Razor markup (.cshtml file) in the web app takes precedence.
If static assets can also be overridden then I'm struggling to get it to work by having a file in
App_Plugins\{PACKAGENAME}\Views\{FILENAME}.html
I've checked the
Microsoft.AspNetCore.StaticWebAssets.Props
file in the nuget package and the
<BasePath>App_Plugins/{PACKAGENAME}</BasePath>
is correct and the asset is in the
staticwebassets/Views/{FILENAME}.html
in the package but don't seem to be able to override with the corresponding physical file on disk? Cheers all.
w
As far as I know I don't think they can, however I am no expert in this. I assume you have installed a package that someone is using RCL approach and you want to overwrite an AngularJS HTML view?
m
Got it in one.. 🙂
Just reading more around staticwebassets and for production (with publish) it would appear they become physical files on disk.. so might be able to replace in a post publish build target? Though have yet to check that.
also wondering if you can do something like
<EmbeddedResource Remove="App_Plugins\{PACKAGENAME}\Views\{FILENAME}.html" />
in the csproj to drop the file I want to change.
So looks like for publish scenarios.. I can use
Copy code
XML
<Target Name="TSD_AfterCopyFilesMarkedCopyLocal" AfterTargets="_CopyFilesMarkedCopyLocal" Condition="Exists('$(Projectdir)..\ExternalDependencies\App_Plugins')">
    <!-- set at the same filepath in ..\ExternalDependencies\App_Plugins to copy over -->
    <!-- for published  -->
    <ItemGroup>
        <TSDAppPluginOverrideFiles Include="$(TsdAppPluginOverrideFilesPath)" />
    </ItemGroup>
    <Message Text="Copying MY App_Plugin Overrides: $(TsdAppPluginOverrideFilesPath) - #@(TSDAppPluginOverrideFiles->Count()) files to $(publishDir)App_Plugins" Importance="high" />
    <Copy SourceFiles="@(TSDAppPluginOverrideFiles)" DestinationFiles="@(TSDAppPluginOverrideFiles->'$(PublishDir)\wwwroot\App_Plugins\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
</Target>
remembering to also add to avoid
Conflicting assets with the same target path
Copy code
xml
    <ItemGroup>
      <Content Remove="Smidge\**" />
      <Content Remove="wwwroot\App_Plugins\DocTypeGridEditor\**" />
    <Content Remove="wwwroot\App_Plugins\UmbracoForms\**" />
      <EmbeddedResource Remove="Smidge\**" />
      <EmbeddedResource Remove="wwwroot\App_Plugins\DocTypeGridEditor\**" />
    <EmbeddedResource Remove="wwwroot\App_Plugins\UmbracoForms\**" />
      <None Remove="Smidge\**" />
      <None Remove="wwwroot\App_Plugins\DocTypeGridEditor\**" />
    <None Remove="wwwroot\App_Plugins\UmbracoForms\**" />
    </ItemGroup>
Though not sure how to do in a dev environment commenting
//webBuilder.UseStaticWebAssets();
in
program.cs
doesn't result in physical files appearing.
using
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
in the csproj kills the backoffice. @Warren Buckley @huwred thanks for looking.. going to park this now.. more pressing things to look at.
(final thought was back to an angular interceptor.....)
j
Was about to say - sounds like an easy job with an angular intercepter if v 13 or lower 🙂
m
Thanks.. it was already in my favourites.. and that does the trick. (just thought there might be a modern alternative like the nice razor file overrides, and one not so wedded to angular)
j
~~Yes, you can override static assets in RCLs. Just pop a file in the same place in your consuming project at the same path as in the RCL and it will just work.~~
m
Yep tried that... didn't work.. as not a razor file.
j
Really? I've literally just done this. Edit: I hadn't.
m
yep really.. checked case sensitivity etc.. and couldn't get it to override.
j
Weird.
~~Well, An RCL's static assets can be overriden. ~~I'm not sure why it's not working in this case.
m
chtml file.. works (but not from wwwroot, from the app_plugins folder proper).. but not html.
so thought that aligned with the ms documentation that only razor based overrides are possible?
and left it at that
j
Ok, not sure what was going on, but you're right.
This is a problem.
m
It does seem to be a short coming with
staticWebAssets
😦
j
Well
It is considering how we use Umbraco... probably not otherwise.
RCL static assets are supposed to be namespaced away to avoid path collisions
It's only because we use App_Plugins in Umbraco that it's become convention to all use the same base path.
m
but aren't we replacing the namespaced
_content/{id}/
with the namespace as the umb (nuget) package name?
shouldn't get collisions on package names?
Copy code
When the app is published, the companion assets from all referenced projects and packages are copied into the wwwroot folder of the published app under _content/{PACKAGE ID}/. When producing a NuGet package and the assembly name isn't the same as the package ID (<PackageId> in the library's project file), use the package ID as specified in the project file for {PACKAGE ID} when examining the wwwroot folder for the published assets.
so we're only really replacing
_content
with
app_plugins
??
j
In theory, yes, though I don't like the root is the same...
Turns out that it doesn't matter anyway
The build wont allow for collison of static asset paths at all.
m
yep only solution I had was above where at publish time.. we can have after build target and replace the companion asset.
but during development when
.UseStaticWebAssets();
is doing the magic.. nada...
j
Indeed, probably better off using a middleware.
m
middelware to intercept the httprequest.. assuming that static assets work like that in development?
j
Static assets are just another middleware, so long as yours runs first you can do what you want with the request.
m
I'm not assuming anything with staticwebassets 😉
might not even have a httprequest at develop time?
and do some other magic..
did wonder why come publish time you get a physical file spat out on disk.. for your staticewebasset.. but not during development.
🤷 way above my knowledge at that point.
j
Have a look in your bin folder for {assemblyname}.staticwebassets.runtime.json
You'll find mappings to all the static assets so .NET knows where to look for them in development mode
m
not sure how that helps.. as just references the nuget package cache? eg
C:\\Users\\mike\\.nuget\\packages\\our.umbraco.umbnav.web\\3.0.1\\staticwebassets\\
can't really be overriding in there?
j
Sorry, was just pointing out how it works in development (and that it's not magic).
m
ah ok.. get ya..
But then the RCL razor files presumably work in a similar fashion.. but with the added bonus of override.. seems odd the same discussion didn't occur around staticWebAssets. 😉
j
They don't work the same way, razor files are compiled so there's no collision in terms of actual files.
Just paths, which are search paths for razor... so I guess it's just a case of "last wins".
I can confirm middleware works, just tested with some backoffice bits
Copy code
csharp
app.Use(async (context, next) =>
{
    if (context.Request.Path.ToString().StartsWith("/App_Plugins/Umbraco.BlockGridEditor.DefaultCustomViews/umbBlockGridDemoHeadlineBlock.html"))
    {
        await context.Response.WriteAsync("Boom!");
        return;
    }
    await next.Invoke();
});
41 Views