Asp.net core 2 - Files are not published - c#

EDIT
For info, I'm developping on macOS using VS Code
I'm trying to include files in my publish process ( Currently cshtmlthat represents my email templates ).
I follow this thread on github but seems that their solutions don't work for me.
Here my csproj to add an unique cshtml file :
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
<ItemGroup>
<EmailFile Include="$(ProjectDir)/EmailTemplates/OrderCompleteEmail.cshtml" />
</ItemGroup>
<Copy SourceFiles="#(EmailFile)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" />
</Target>

Your solution was almost correct, you have to use AfterTargets="Publish":
<Target Name="CopyCustomContentOnPublish" AfterTargets="Publish">
<ItemGroup>
<EmailFile Include="EmailTemplates/OrderCompleteEmail.cshtml" />
</ItemGroup>
<Copy SourceFiles="#(EmailFile)" DestinationFolder="$(PublishDir)" />
</Target>
You can also copy all your email templates in a single Target to the same folder like:
<Target Name="CopyCustomContentOnPublish" AfterTargets="Publish">
<ItemGroup>
<EmailTemplates Include="EmailTemplates\*.cshtml" />
</ItemGroup>
<Copy SourceFiles="#(EmailTemplates)" DestinationFolder="$(PublishDir)%(EmailTemplates.RelativeDir)" />
</Target>

Related

Visual Studio - Change target framework when multitargeting

IS there a way to change what framework a project (that has multiple target frameworks) is compiled in without updating the csproj?
I'm writing a NuGet package that supports both .NET 4.8 and .NET 6. (I can't use .NET Standard 2.0.)
I have files that I want to be compiled only when targeting .NET 4.8 and others that should only be compiled when targeting .NET 6.0. I know there's a couple ways to achieve this, but I am trying to structure my files such that the directory /AspNetCore contains all of my .NET 6 files and /NetFramework contains all my .NET 4.8 files.
With that, in my csproj, I can do:
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<Compile Remove="NetFramework\**" />
<EmbeddedResource Remove="NetFramework\**" />
<None Remove="NetFramework\**" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<Compile Remove="AspNetCore\**" />
<EmbeddedResource Remove="AspNetCore\**" />
<None Remove="AspNetCore\**" />
</ItemGroup>
But then the /AspNetCore folder is hidden because the IDE is choosing NET48 as the target framework. This is fine when I'm working on the NET48 code, but not ideal when I'm working on the NET6.0 code.
If I were using #if NETFRAMEWORK #elif NET6_0 #endif syntax in each file, then I could select the target framework from the project dropdown, but I want to avoid having compile-time logic in my files. I could also keep going back to my csproj and updating the tag, but I don't want to do that either in case I accidentally forget to change it back.
Is there a good to change the target framework in the IDE when targeting multiple frameworks like this?
Create a Directory.Build.targets file in your solution folder and copy the contents below:
<Project>
<PropertyGroup>
<BuildDependsOn>
RemoveNet48Files;
RemoveNet60Files;
$(BuildDependsOn)
</BuildDependsOn>
</PropertyGroup>
<Target Name="RemoveNet48Files" Condition="'$(TargetFramework)' != 'net48'">
<ItemGroup>
<Compile Remove="NetFramework\**" />
<EmbeddedResource Remove="NetFramework\**" />
<None Remove="NetFramework\**" />
</ItemGroup>
</Target>
<Target Name="RemoveNet60Files" Condition="'$(TargetFramework)' != 'net6.0'">
<ItemGroup>
<Compile Remove="AspNetCore\**" />
<EmbeddedResource Remove="AspNetCore\**" />
<None Remove="AspNetCore\**" />
</ItemGroup>
</Target>
</Project>
This way the files will be removed from the item group only before build.

Restoring dotnet tools found in csproj file. What does this mean for my project?

The csproj file of my newly created Android project in VS for Mac 2022 looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-android</TargetFramework>
<SupportedOSPlatformVersion>31</SupportedOSPlatformVersion>
<OutputType>Exe</OutputType>
<ApplicationId>com.companyname.TestProjectAndroid</ApplicationId>
<ApplicationVersion>1</ApplicationVersion>
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
<PackageReference Include="MonoGame.Framework.Android" Version="3.8.1.303" />
</ItemGroup>
<ItemGroup>
<None Remove="proguard.cfg" />
</ItemGroup>
<ItemGroup>
<ProguardConfiguration Include="proguard.cfg" />
</ItemGroup>
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
<Message Text="Restoring dotnet tools" Importance="High" />
<Exec Command="dotnet tool restore" />
</Target>
</Project>
At the end it has Restoring dotnet tools and Importance="High". What does this Restoring dotnet tools mean? Is something wrong with my project?
I use VS for Mac 2022 17.3.8 (build 5).

How to fix version conflict for MicrosoftEntityFrameworkCore

I create a WEB API in .NET CORE with the 'dotnet new' command. i want to configure this with Entity Framework Core but i cant. I install this with the 'Manage Nugets Pakages' in VS2017 and VS give me a error.
I tried to restore packages but the error persist.
my csproj file:
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CORE\CORE.csproj" />
<ProjectReference Include="..\DAL\DAL.csproj" />
<ProjectReference Include="..\DOORACCESS\DOORACCESS.csproj" />
<ProjectReference Include="..\DPFINGER\DPFINGER.csproj" />
<ProjectReference Include="..\LOGIC\LOGIC.csproj" />
<ProjectReference Include="..\utest\utest.csproj" />
</ItemGroup>
</Project>
As you can see download the packages but do not add them to the csproj. I tried to do it manually, but when I put it in, I was asking for its dependencies one by one.

Embedding resources after build?

I currently have a build setup as follows, allowing me to embed all references DLLs as embedded resources in my assembly. This operates at the AfterResolveReferences target and works flawlessly. It also allows me to produce a single executable which doesn't need any additional DLLs to launch (since it loads these at runtime).
Now, I would like to include the PDB information as well. I already do this with all referenced assemblies, but not the assembly I am building, since that is (for obvious reasons) produced after that target.
To recap:
I am building AssemblyA.exe.
It has AssemblyB.dll and AssemblyC.dll as references, so these are included in AssemblyA.exe as embedded resources during build.
After building AssemblyA.exe, MSBuild also produces a AssemblyA.pdb file.
This is where I want to then also embed AssemblyA.pdb into AssemblyA.exe as embedded resource.
Is that possible somehow? I am aware that this may trigger a double-build.
I ended up writing the following to my project file - works flawlessly. It does a double-build, but it works.
<Target Name="Prebuild">
<CallTarget Targets="Clean" />
<MSBuild Projects="$(SolutionPath)" Targets="Build" Properties="Configuration=Debug;IgnoreRecursion=true" />
</Target>
<Target Name="BeforeBuild">
<ItemGroup>
<_IgnoreRecursion Include="$(IgnoreRecursion)"/>
</ItemGroup>
<CallTarget Targets="Prebuild" Condition="'%(_IgnoreRecursion.Identity)' != 'true'" />
<CreateItem Include="$(TargetDir)\**\*.*">
<Output TaskParameter="Include" ItemName="OutputFiles" />
</CreateItem>
<ItemGroup>
<EmbeddedResource Include="#(OutputFiles)" Condition="('%(OutputFiles.Extension)' == '.dll' Or '%(OutputFiles.Extension)' == '.pdb')">
<LogicalName>%(OutputFiles.DestinationSubDirectory)%(OutputFiles.Filename)%(OutputFiles.Extension)</LogicalName>
</EmbeddedResource>
</ItemGroup>
<Message Importance="high" Text="Embedding: #(OutputFiles->'%(Filename)%(Extension)', ', ')" />
</Target>
If a double compile is not a problem you can create your own target, compile to a temporay folder via msbuild task and then embed the files you need from this temporary folder.
You have to do a rebuild because otherwise it will cache the assemblies.
Your target to compile in the .proj file would look like this:
<Target Name="YourBuild">
<MSBuild Projects="YourProject.csproj" Targets="Build"
Properties="Configuration=Debug;OutputPath=tmp"/>
<MSBuild Projects="YourProject.csproj" Targets="Rebuild"
Properties="Configuration=Debug"/>
</Target>
Files that are included as EmbeddedResoucre in BeforeBuild target in the project:
<Target Name="BeforeBuild">
<ItemGroup>
<YourFiles Include="tmp\*.pdb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="#(YourFiles ->'%(Relativedir)%(filename)%(extension)')"/>
</ItemGroup>
</Target>

MVCBuildViews not working correctly

So I edited my csproj file on an MVC 3 RTM application to set the following property:
<MvcBuildViews>true</MvcBuildViews>
This should cause my views to be complied during build and force a build error if my view is broken. This is the only change I made, however, when I try to build the application, I get the following error:
It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.
The project compiles and runs successfully if I change back to false,
The following are the build tasks configured in the csproj file (these were never manually edited, they were added by Visual Studio 2010)
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target> -->
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
Am I missing something here? How do I get MVC 3 / Visual Studio 2010 configured correctly to validate my views at build time?
I had this problem a few days ago and I fixed it by deleting obj/Debug folder. Cleaning the project also works. I have no idea about the cause of the issue, though.
See Joe Cartano's answer for a more permanent solution.
This problem occurs when there is web project output (templated web.config or temporary publish files) in the obj folder. The ASP.NET compiler used isn't smart enough to ignore stuff in the obj folder, so it throws errors instead.
Another fix is to nuke the publish output right before calling <AspNetCompiler>. Open your .csproj and change this:
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
to this:
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<ItemGroup>
<ExtraWebConfigs Include="$(BaseIntermediateOutputPath)\**\web.config" />
<ExtraPackageTmp Include="$([System.IO.Directory]::GetDirectories("$(BaseIntermediateOutputPath)", "PackageTmp", System.IO.SearchOption.AllDirectories))" />
</ItemGroup>
<Delete Files="#(ExtraWebConfigs)" />
<RemoveDir Directories="#(ExtraPackageTmp)" />
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
That will delete all web.configs under \obj, as well as all PackageTmp folders under \obj.
UPDATE:
Even better, based off https://stackoverflow.com/a/48582282/8037 you can exclude the obj folder entirely. Apparently the <AspNetCompiler /> task doesn't have an exclude parameter, but if you switch to calling the aspnet_compiler .exe directly, you can exclude obj like this:
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<Exec Command="$(MSBuildFrameworkToolsPath)aspnet_compiler.exe -v temp -p $(WebProjectOutputDir) -x $(BaseIntermediateOutputPath)"/>
</Target>
When you get this error do you have another web.config file in your obj folder? If you are using MSDeploy this might help: MSDN Blog: The Aspnet Compiler Build Task in Visual Studio 2010 ASP.Net MVC 2 Projects, if not, maybe another web.config is being generated by some tool you are running.
This is what worked for me. Optionally, you may specify a condition with the configuration.
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
<Target Name="AfterBuild" Condition="'$(Configuration)'!='Debug'">
<RemoveDir Directories="$(BaseIntermediateOutputPath)" />
</Target>
This issue of Compile-time View Checking even though MvcBuildViews is set to 'true' is well-explained in the following MSDN blog:
https://blogs.msdn.microsoft.com/jimlamb/2010/04/20/turn-on-compile-time-view-checking-for-asp-net-mvc-projects-in-tfs-build-2010/
You could do the fix by editing .csproj file directly:
<PropertyGroup>
<MvcBuildViews>true</MvcBuildViews>
</PropertyGroup>
<Target Name="BuildViews" Condition="'$(MvcBuildViews)'=='true'" AfterTargets="Build">
<Message Importance="normal" Text="Precompiling views" />
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
A simple solution kinda compiled from the other answers here
You can simply remove the whole /obj folder like this:
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" /> <!--add this line-->
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>

Categories