Embed files for a Nuget ASP.NET Core package
For NetCoreBlockly I have the need to embed some files in the NUGET package (https://www.nuget.org/packages/NetCore2Blockly ) to display a GUI.
After unsuccessful trying to deploy, I have read https://weblog.west-wind.com/posts/2018/Jan/29/Distributing-Content-and-Showing-a-ReadMe-file-in-a-NET-Core-Nuget-Package .
So I must learn from the experts: e.g. , swagger : https://github.com/domaindrivendev/Swashbuckle.AspNetCore it is displaying the HTML UI. How it does ? By embedding into the .csproj the index.html : https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerUI/Swashbuckle.AspNetCore.SwaggerUI.csproj
But NetCoreBlockly have more than 1 file – more js, more css … and I want to be done automatically.
So I solved this in 3 steps:
- I Embed all files from a folder in the nuget csproj
<ItemGroup>
<EmbeddedResource Include=”blocklyFiles\**\*”>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
2. In the NuGet I obtain the files as embedded
var manifestEmbeddedProvider =
new ManifestEmbeddedFileProvider(Assembly.GetExecutingAssembly());
3. I generate ASP.NET Core endpoints for each file from the Embed, according to the tree :
private static void mapFile(string dirName, IFileProvider provider, IApplicationBuilder appBuilder) { var folder = provider.GetDirectoryContents(dirName); foreach (var item in folder) { if (item.IsDirectory) { mapFile(dirName + "/" + item.Name, provider, appBuilder); continue; } string map = (dirName + "/" + item.Name).Substring("blocklyFiles".Length); appBuilder.Map(map, app => { var f = item; app.Run(async cnt => { //TODO: find from extension //cnt.Response.ContentType = "text/html"; using var stream = new MemoryStream(); using var cs = f.CreateReadStream(); byte[] buffer = new byte[2048]; // read in chunks of 2KB int bytesRead; while ((bytesRead = cs.Read(buffer, 0, buffer.Length)) > 0) { stream.Write(buffer, 0, bytesRead); } byte[] result = stream.ToArray(); var m = new Memory<byte>(result); await cnt.Response.BodyWriter.WriteAsync(m); }); }); } }
Optional:
4. Because I need to test , copy the files in the CI from a real ASP.NET Core website to the .csproj with the NUGET package
5. You can replace some tags with your values – or just use a .js file that generates options ( see BlocklyUIOptions below)
If you want to see in Action, browse to https://netcoreblockly.herokuapp.com/blockly.html
If you want to see the code, goto https://github.com/ignatandrei/NETCoreBlockly/blob/master/src/NetCore2Blockly/NetCore2Blockly/ExtensionMethods/CLIExtension.cs and see public static void UseBlocklyUI(this IApplicationBuilder appBuilder, BlocklyUIOptions options =null)
Leave a Reply