I'm working on a project structure with multiple projects serving the same set of static files.
At start each project will server both the static files and the API services but later on I plan to separate some of them into multiple projects.
ProjectA will server both static files and API
ProjectB1 will only serve the same static files as in ProjectA
ProjectB2 will only serve the API
In a classic VS library you can have files marked as content. These will be included in the build output of any project that references that library.
I tried to make a project ProjectStatic containing the static files and reference it from both ProjectA and ProjectB1 but none of the files in ProjectStatic are included in the output of ProjectA nor ProjectB1.
Can this be done using project.json?
You can use the UseStaticFiles call with a EmbeddedFileProvider. It's part of the rc1-final package, as you can see here.
Just for future readers:
app.UseStaticFiles(new StaticFileOptions {
FileProvider = new EmbeddedFileProvider(
assembly: Assembly.Load(new AssemblyName("OpenIddict.Assets")),
baseNamespace: "OpenIddict.Assets")
});
OpenIddict.Assets is the assembly/project name that contains the static resources.
Update:
After digging a bit through the source and finding the right repository, there is also a PhysicalFileProvider you may be able to use instead of packing it into the assembly and point to an arbitrary folder on the file system.
app.UseStaticFiles(new StaticFileOptions {
FileProvider = new PhysicalFileProvider("/path/to/shared/staticfiles")
});
Update 2:
Just for the sake of completeness, there is also a CompositeFileProvider which you could use to have multiple IFileProviders to create some kind of virtual file system structure, i.e. if the file is not found in the PhysicalFileProvider given location, load it from an EmbeddedFileProvider.
Related
There is a lot of hidden magic that occurs in HostBuilder.ConfigureWebHostDefaults() (that eventually calls ConfigureWebDefaults). I would like to understand it better as there is no documentation that I can find about it.
This code seems to be loading some static files. What are static web assets and why do we need them? Is this something to do with embedding static assets into libraries for Blazor?
builder.ConfigureAppConfiguration((ctx, cb) =>
{
if (ctx.HostingEnvironment.IsDevelopment())
{
StaticWebAssetsLoader.UseStaticWebAssets(ctx.HostingEnvironment, ctx.Configuration);
}
});
Static Web Assets are static files made available from a Razor Class Library (RCL):
An RCL may require companion static assets that can be referenced by the consuming app of the RCL. ASP.NET Core allows creating RCLs that include static assets that are available to a consuming app.
UseStaticWebAssets inserts additional file providers (instances of StaticWebAssetsFileProvider), using a manifest file ({environment.ApplicationName}.StaticWebAssets.xml if not set via IConfiguration) to determine a list of mappings from path to base path.
As an example, when using the ASP.NET Core Identity UI RCL, the manifest file for your app looks something like this:
<StaticWebAssets Version="1.0">
<ContentRoot BasePath="/Identity" Path="\path\to\.nuget\packages\microsoft.aspnetcore.identity.ui\3.0.0\staticwebassets\V4" />
</StaticWebAssets>
This all ends up with a CompositeFileProvider being set for the IWebHostEnvironment.WebRootFileProvider. This composite provider does two things:
Processes the wwwroot/ static files as usual (assuming default configuration).
Delegates any files requested from wwwroot/Identity to the extracted NuGet package content folder for the Identity UI.
As the code snippet from your question shows, this only happens when running in the Development environment. When your app is published, the files in question get copied up into the wwwroot folder, as though they were part of your app.
When using Angular 5 with ASP.NET Core, a new Visual Studio project contains both a wwwroot folder and an assets folder:
The question is: In which folder should static content (images, css, etc.) be placed, and when would you use one vs. the other?
According to answers online, the wwwroot folder is where static content should go:
The wwwroot folder is new in ASP.NET 5.0. All of the static files in your project go into this folder. These are assets that the app will serve directly to clients, including HTML files, CSS files, image files, and JavaScript files.
However, according to Angular's documentation, static content can also go into the assets folder:
You use the assets array in .angular-cli.json to list files or folders you want to copy as-is when building your project.
All static stuff used and referenced in Angular should go to assets. All static stuff, used in MVC Views, in ASP.NET Core directly should go to wwwroot.
During build/deployment/publish, the built Angular app, will be copied to wwwroot automatically, because this is the root folder for static contents for ASP.NET Core apps. (So the Angular artifacts becomes static contents from the ASP.NET Core view. But you shouldn't need to do this manually.)
Just some additional information on this. I run into a similar situation today while taking a look at an app that my company is about to redesign, I found static files in both wwwroot and assets folders.
Based on the screenshot in the question the project has been created with the Net Core Angular Template that comes with Visual Studio: https://learn.microsoft.com/en-us/aspnet/core/client-side/spa/angular?view=aspnetcore-3.1&tabs=visual-studio (the same template used on the project I was looking at today). By default, you will get a folder structure like this one (screenshot of fresh project attached):
where the favicon.ico is in the wwwroot folder, so you could continue adding images and other static files in the wwwroot folder and the app will work fine. The template is configured to use the folder "ClientApp/dist" in production (Image attached from a fresh project created using the Angular template for .NET Core 3.1) assuming you will serve all as one service.
So, both approaches will work but the assets folder seems to be a better place. That was the place I was expecting to find static files for the Angular app as a developer.
The practical advantage I see from keeping the static files in the Angular project (folder ClientApp/src/assets) is that if you decide along the way to deploy and serve the client app separately you can just grab the angular build which includes the assets folder and move them to the server without additional work.
I have a .NET Core 2.0 solution containing 3 projects (DataAccess, Services, WebAPI). In the wwwroot folder of the WebAPI project I've created a templates folder that contains a couple of Excel template files. In Services I have an Export folder which contains the ExportService. The ExportService uses the templates to generate some reports. I have a private method that 'gets' the path to the templates directory. In fact I'm just specifying a relative path to it, which works fine when debugging, but not when I publish the project. How can I make the files available/reachable in my published app?
private string GetExcelTemplatePath()
{
var templatesDirectory = "..\\WebAPI\\wwwroot\\templates";
var templateName = "Excel_template_v1.xlsx";
var templatePath = Path.Combine(templatesDirectory, templateName);
return templatePath;
}
With ASP.NET Core you’ll want to inject IHostingEnvironment into your controller (or wherever you need this). From that object you can get WebRootPath which contains the path to wwwroot. Use that to find the files inside it.
More information from the web.
Going nuts :-)
I've installed the latest ASP.NET Core (RC2).
I'd like to be able to create a *.sln, with multiple *.csproj: one for server side development, and one for just client side development.
The reason we are keeping them separate is so that we can have the option of giving the the clientside *.csproj to external developers with better UI skills to work on without needing to know much about the server side code. They could work on the client side html/js using Visual Studio Code or other light weight IDE, and not requiring Visual Studio to get involved.
In the client *.csproj, I'd like to serve static files (html/js/css) for an angular project from the root directory, not from the wwwroot directory, so that gulpfile.js relative paths, etc are identical to how one would set up an angular project without Visual Studio.
As I understand it, the rules are now:
* use the webroot setting in hosting.json if hosting.json file exists.
* otherwise, use wwwroot.
* if that's missing, use root.
* See: https://github.com/aspnet/Hosting/issues/450
First, checked that I had set up static page routing. Created a wwwroot/index.html page. Tada! Works.
Now, renamed the directory to app/ and updated hosting.json to point to it. After a reload of the project, the app/ folder changed icon..good...run...no joy. Fight with it for a while. No success...
Then delete the app/ folder and hosting.json file altogether. End up definitely wanting to throw something...
The only way I'm getting static files is if the folder is called wwwroot. Whether I have a hosting.json file or not.
That's contrary to the documentation at: https://github.com/aspnet/Hosting/issues/450
Has anybody else succeeded in getting rid of the wwwroot folder? If so...how?!?!?
Thank you!
Although you can open up the root of your ASP.NET Core app for serving static files, it's not a good idea because once you do, there's nothing preventing someone from navigating to project.json or any other file in the root.
That being said, here's how you would go about serving up static files outside of wwwroot.
First, create a static class that returns IApplicationBuilder. In here you will define what physical path to make accessible along with an optional URL re-write of that path (see comments in the code):
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.FileProviders;
public static class ApplicationBuilderExtensions
{
public static IApplicationBuilder UseRootResources(this IApplicationBuilder app, HostingEnvironment env)
{
//var path = Path.Combine(env.ContentRootPath); // WARNING - this opens up the root of the app
var path = Path.Combine(env.ContentRootPath, "static"); // this would allow for serving up contents in a physical path folder named 'static'
var provider = new PhysicalFileProvider(path);
var options = new StaticFileOptions();
// the below line re-writes the path name of the physical path, it can have the string value of anything you want to call it
options.RequestPath = ""; // in this example, an empty string will give the *appearance* of it being served up from the root
//options.RequestPath = "/static"; // this will use the URL path named static, but could be any made-up name you want
options.FileProvider = provider;
app.UseStaticFiles(options);
return app;
}
}
Next, in the Startup.cs, call that function from the Configure method:
app.UseRootResources((HostingEnvironment)env);
Now you can serve up static files outside of wwwroot! Referencing the static file in HTML will use the path you defined in the Options.RequestPath as set in the ApplicationBuilderExtensions class. Assuming you left the RequestPath to an empty string to simulate the root, you then call the resource like it lived there (even though it really lives in the 'static' folder) thanks to the magic of URL re-writing:
<img src="bus.jpg"/>
I used the ex_docs package to automatically generate documentation regarding my project modules in a Phoenix Framework project.
Then with mix docs I successfully created the doc folder at the root of the project.
However the contained files are full-fledged html files instead of templates.
How can I route to these files with the Router?
The documentation is generated as static HTML files. You can serve static files with phoenix from the priv/static directory, copy your files from doc/ to the static directory.
You can find the configuration for the static file in your endpoint.ex file, see plug for documentation: http://hexdocs.pm/plug/Plug.Static.html.