BundlerMinifierCore files are not copied on dotnet publish - css

I had an ASP.NET Core 1.1 application, which was upgraded from Visual Studio 2015 using project.json to Visual Studio 2017 with the MsBuild csproj standard. The app is deployed to a docker container on linux, where the official images from microsoft are used. BundlerMinifier were missing. But only on docker, not in Visual Studio 2017 and not using dotnet publish on Windows 10.
I found out, that the bundles were generated. But in the wwwroot folder of the solution, not in the publish output folder (passed by --output to dotnet publish). Lets say, I have /app where my VS solution is located in the docker container. Now I run dotnet publish --output /app/output. My bundled files are now in /app/src/{projectName}/wwwroot instead of /app/output/wwwroot where I need them.
I use relative paths in the bundleconfig.json like this:
[
{
"minify": { "enabled": false },
"outputFileName": "wwwroot/site.min.css",
"inputFiles": [
"wwwroot/lib/my-input-file.css"
]
}
]
To create the bundle, I have the following publishing scripts in my csproj file
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
<Exec Command="bower install" />
<Exec Command="dotnet bundle" />
</Target>
I'm not very familar with MsBuild. But according to some researchs, the following lines seems responsible to copy files to the output directory (like wwwroot)
<ItemGroup>
<None Update="wwwroot\**\*;Views\**\*.cshtml;Areas\**\*.cshtml">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>
Since wwwroot is already included here and the copying of other files like Views works, I thought there is an issue about execution ordner. Something like MsBuild copy the files before MsBuild is publishing them. But this seems not possible from the logic, since this is done before PrepareForPublish target, which is - according to Microsoft docs - the right way.

That's because you don't include the files in the wwwroot.
<ItemGroup>
<None Update="wwwroot\**\*;Views\**\*.cshtml;Areas\**\*.cshtml">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>
wwwroot\**\* will only copy over the files in subfolders of wwwroot (at least this was still the case with the old project.json structure), but your css file is in wwwroot/site.min.css. So either move them to wwwroot/css/site.min.css. Or easier: Just publish the copy over the whole wwwroot folder (and keep your libs files outside of wwwroot, like in bower_modules or npm_modules):
Also I'm not sure of <None> is the right tag for it. In my project's csproj there is only <None Include="App.config" /> and the files I copy over are in <Content>, like below
<ItemGroup>
<None Include="App.config" />
<Content Update="wwwroot;Views;Areas;appsettings.json;web.config">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
As you shouldn't have any unrelated files in Views and Areas it's easier to copy over the whole folders too.

Related

How to copy .net core project's xdt-transformed file to referencing project's output?

I have two .net core (3.1) projects Project A --References--> Project B.
Project B contains a content directory with an XML content file.
I want to xdt transform this content file in Project B and to get it copied to output directory of Project B and to output directory of Project A as well.
I have managed to get it transformed and get copied to output directory of Project B. However its not getting copied to output directory of Project A.
Content files in Project B are described in project B as -
<ItemGroup>
<None Update="ContentFolder\content.config">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="ContentFolder\content.Release.config">
<DependentUpon>Sirius.Api.Team.config</DependentUpon>
</None>
</ItemGroup>
The transformation task in Project B is specified as
<Target Name="ApplyXdtConfigTransform" BeforeTargets="BeforeBuild" Condition="Exists('ContentFolder\content.$(Configuration).config')">
<Message Importance="high" Text="Running custom task (Target Name 'ApplyXdtConfigTransform') from '$(MSBuildProjectFile)' to transform 'ContentFolder\content.config'.%0aReference - https://github.com/nil4/dotnet-transform-xdt, https://medium.com/we-code/config-transformation-for-net-core-f5abfaa78807 %0aTransforming '$(MSBuildThisFileDirectory)ContentFolder\content.config' using transform '$(MSBuildThisFileDirectory)App.$(Configuration).config'" />
<PropertyGroup>
<_SourceWebConfig>$(MSBuildThisFileDirectory)ContentFolder\content.config</_SourceWebConfig>
<_XdtTransform>$(MSBuildThisFileDirectory)ContentFolder\content.$(Configuration).config</_XdtTransform>
<_TargetWebConfig>$(PublishDir)ContentFolder\content.config</_TargetWebConfig>
</PropertyGroup>
<Exec Command="dotnet xdt --verbose --xml "$(_SourceWebConfig)" --transform "$(_XdtTransform)" --output "$(_TargetWebConfig)"" Condition="Exists('$(_XdtTransform)')" />
<Message Importance="high" Text="Transformation completed, file saved as '$(_TargetWebConfig)'" />
</Target>
How do I specify to have the transformed file to get copied to Project A's output directory that references Project B?

.NET Core Console include specific folder when publishing

I want to include a specific folder and its subdirectories when I publish the .NET Core Console application. I added the following code in the Properties/PublishProfiles/FolderProfile.pubxml file.
<ItemGroup>
<_CustomFiles Include="$(MSBuildProjectDirectory)/../Templates/**/*" />
<DotNetPublishFiles Include="#(_CustomFiles)">
<DestinationRelativePath>Templates/%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</DotNetPublishFiles>
</ItemGroup>
but this code does not work.
The weird thing is that, those code works when I publish my .NET Core Web API project.
Is there any difference for the configuration between Web API and .NET Core Console?
What i actually do is to update the item's build profile which allows the respective folder and the contents included in the publish directory as well.
Something like this below appears in the .csproj file
<ItemGroup>
<None Update="depends\Bitmap1.bmp">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

How to discover .js, .css files, what are in the filesystem (and repo) but not in .csproj?

Context
I regularly make the mistake to forget include a vendor .css or .js to the Asp Mvc project. I just copy/download with a tool, or from a theme, and referencing them. All works locally because the files are in the virtual directory so IIS Express will server them.
When publish times come, and I publish the new version, those files which are not in the .csproj will not be deployed.
Question
Although some tools or itself the IDE creates warning in some cases if in a syntax construct I refer to a resource what is not in the .csproj, this is not all working (for example: when using BundleConfig)
It seems to be pretty simple prevent this source of errors: Just check the file system with a well picked filter and list all files what are not included in the .csproj. (the filter could be: (*.css, .js, ...) or (assets/.*)
How can I accomplish this task?
If you switch to the new .csproj format supported by Visual Studio 2017, you no longer need to add references to files in the file system, they are picked up by default and you have to exclude files that you don't want.
Migration to the new .csproj format is pretty straightforward - you can use the dotnet migrate tool to make the conversion.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net47</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MyProj\MyProj.csproj" />
</ItemGroup>
<ItemGroup>
<!-- /* Exclude files you don't want */ -->
<Compile Remove="Text\AnyTransliterator.cs" />
<Compile Remove="Text\BreakTransliterator.cs" />
</ItemGroup>
</Project>
If you have files outside of your project directory that you want to include, you can create a link to a file or directory.
<!-- /* Link to an individual file outside of the project */ -->
<Content Include="..\..\..\Assets\something.css" Link="Assets\something.css" />
<!-- /* Create a virtual directory in Visual Studio named Assets
and link to external Assets directory. All files in that
directory will be included in the project */ -->
<Content Include="..\..\..\Assets\**\*" LinkBase="Assets" />
<!-- /* Create a virtual directory in Visual Studio named Assets
and link to external Assets directory. Only .css files in that
directory will be included in the project */ -->
<Content Include="..\..\..\Assets\**\*.css" LinkBase="Assets" />
This works with .NET Framework, but do note that you need to install the .NET Core SDK 2.0.0 in addition to VS 2017 15.3 (and ensure no global.json selects a lower SDK version) for the LinkBase option to work.
Reference: New .csproj format - How to specify entire directory as "linked file" to a subdirectory?

ASP.NET core RazorPages - No executable found matching command "dotnet-bundle"

I know - can see related questions for ASP.NET MVC projects & talk around project.json files but i'm using the default project with ASP.NET core with Razor pages & all i believe the equivalent file to edit is the *.csproj file - I've seen a few of the answers do relate to the *.csproj file & i have followed them with still no joy :/ Being new i can't add comments to those answers directly so thought a new post best..
Using VS-2017. Basic project created via /.NET Core/ASP.NET Core Web Application/"Web Application" (just in case i'm leading anyone astray) and with a single test edits made to site.css to test minification.
via NuGet package manager window confirmed BundlerMinifier.Core v2.6.362 is installed
.csproj file contents:
<Project ToolsVersion="15.0" Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BundlerMinifier.Core" Version="2.6.362" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.1" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.1" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="BundlerMinifier.Core" Version="2.6.362" />
</ItemGroup>
</Project>
Project saved and built.
When running "dotnet bundle" in the Package Manager Console i get result:
PM> dotnet bundle
dotnet : No executable found matching command "dotnet-bundle"
At line:1 char:1
+ dotnet bundle
+ ~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (No executable f..."dotnet-bundle":String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
PM>
i honestly have not further clue why this isn't working!??
Ideally all i want to do is incorporate custom css & js into the project, i'm led to believe this is the 'proper' way.. maybe there is a better (i.e. simpler) solution? No idea why this isnt part of the default template, assuming that the template is meant for beginners?..
THANKS!
This is a valid problem.
The root is that for some reason the executing directory is not set to the same as what you have selected in VS as the default project.
Try entering dir in package manager console. If you are not in your project directory, cd into your project and run dotnet bundle again.

Copy Files after Publish events

I'm trying to copy reports with a "batch script" through MSBuild. I currently have a project that is targeting v3.5 in Visual Studio 2012.
I modified my website.publishproj and added:
<Target Name="MyTarget" AfterTargets="CopyAllFilesToSingleFolderForPackage" >
<Exec Command="echo ###################################### Copying Reports #################################" />
<Exec Command="xcopy.exe $(MSBuildProjectDirectory)\..\MoteurRapports $(PublishURL)\Rapports\ /S /E /H /EXCLUDE:$(MSBuildProjectDirectory)\CopyRapportExclude.txt" />
</Target>
But when I publish it:
254 files(s) copied
**Deleting existing files...**
Publishing folder /...
Publishing folder AideHTML...
It deletes the files I just copied. Is there a target after the deletion that I can use with the publish wizard?
I believe you may need to add this argument to your msbuild cmd. That will keep it from "cleaning" any files it believes are not part of the deployment.
/p:SkipExtraFilesOnServer=True

Resources