Mapster generation output directory - c#

The structure of the project looks so that for each entity a separate folder is allocated, which stores the mapper interface, but the generation occurs in the directory above. I need to make the mapper class be generated in the same directory as the interface regardless of the directory name.
example
My settings:
<ItemGroup>
<Generated Include="**/*.g.cs" />
<!--to clean up generated files dotnet msbuild -t:CleanGenerated-->
</ItemGroup>
<Target Name="CleanGenerated" BeforeTargets="build">
<Delete Files="#(Generated)" />
</Target>
<Target Name="Mapster" AfterTargets="AfterBuild">
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool restore" />
<!--<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster model -a "$(TargetDir)$(ProjectName).dll"" />
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster extension -a "$(TargetDir)$(ProjectName).dll"" />-->
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster mapper -a "$(TargetDir)$(ProjectName).dll"" />
</Target>
Changing the values of the property Generated Include="**/*.g.cs" did not bring any results
as well as the use of different options for Mapster.Tool (tried -n -b and -o)

Related

No executable found matching command "dotnet-/app/Build\ClearPluginAssemblies.dll" Docker

I'm trying to run my ASP.NET Core 2.1 application with docker image. For that I have docker file with the following content:
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /app
# copy csproj and restore as distinct layers
COPY . .
RUN dotnet restore
# copy everything else and build app
COPY Presentation/MyProject.Web/. ./Presentation/MyProject.Web/
WORKDIR /app/Presentation/MyProject.Web
RUN dotnet publish -c Release -o out
# Build runtime image
FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build /app/Presentation/MyProject.Web/out .
ENTRYPOINT ["dotnet", "MyProject.Web.dll"]
But when execute the command docker build -t MyProject-web . it gives me an error:
The command '/bin/sh -c dotnet publish -c Release -o out' returned a non-zero code: 1
MyProject.Web -> /app/Presentation/MyProject.Web/bin/Release/netcoreapp2.1/MyProject.Web.dll
No executable found matching command "dotnet-/app/Build\ClearPluginAssemblies.dll"
/app/Build/ClearPluginAssemblies.proj(21,5): error MSB3073: The command "dotnet "/app/Build\ClearPluginAssemblies.dll" "OutputPath=/app/Build/../Presentation/MyProject.Web/bin/Release/netcoreapp2.1/|PluginPath=/app/Presentation/MyProject.Web/Plugins/DiscountRules.CustomerRoles/;/app/Presentation/MyProject.Web/Plugins/ExchangeRate.EcbExchange/;/app/Presentation/MyProject.Web/Plugins/ExternalAuth.Facebook/;/app/Presentation/MyProject.Web/Plugins/Payments.CheckMoneyOrder/;/app/Presentation/MyProject.Web/Plugins/Payments.Manual/;/app/Presentation/MyProject.Web/Plugins/Payments.PayPalStandard/;/app/Presentation/MyProject.Web/Plugins/Payments.Square/;/app/Presentation/MyProject.Web/Plugins/Payments.Worldpay/;/app/Presentation/MyProject.Web/Plugins/Pickup.PickupInStore/;/app/Presentation/MyProject.Web/Plugins/Shipping.FixedByWeightByTotal/;/app/Presentation/MyProject.Web/Plugins/Shipping.UPS/;/app/Presentation/MyProject.Web/Plugins/Tax.FixedOrByCountryStateZip/;/app/Presentation/MyProject.Web/Plugins/Widgets.GoogleAnalytics/;/app/Presentation/MyProject.Web/Plugins/Widgets.NivoSlider/|SaveLocalesFolders="" exited with code 1.
The command '/bin/sh -c dotnet publish -c Release -o out' returned a non-zero code: 1
Edit 1:
Here is my project structure:
Build
ClearPluginAssemblies
Libraries
MyProject.Core
MyProject.Data
MyProject.Services
Plugins
MyProject.Plugin.Discount
MyProject.Plugin.Payment
..
Presentation
MyProject.Web
MyProject.Web.Framework
Tests
Edit:2 Web project file:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<Description>MyProject.Web is also an MVC web application project, a presentation layer for public store and admin area.</Description>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\MyProject.Core\MyProject.Core.csproj" />
<ProjectReference Include="..\..\Libraries\MyProject.Data\MyProject.Data.csproj" />
<ProjectReference Include="..\..\Libraries\MyProject.Services\MyProject.Services.csproj" />
<ProjectReference Include="..\MyProject.Web.Framework\MyProject.Web.Framework.csproj" />
</ItemGroup>
<ItemGroup>
<!-- We copy the entire \App_Data directory. But we ignore JSON files and data protection keys -->
<Content Include="App_Data\**" CopyToPublishDirectory="PreserveNewest" Exclude="App_Data\*.json" />
<Content Update="App_Data\*.json" CopyToPublishDirectory="Never" />
<Content Update="App_Data\DataProtectionKeys\*.xml" CopyToPublishDirectory="Never" />
<Compile Remove="Plugins\**" />
<EmbeddedResource Remove="Plugins\**" />
<None Remove="Plugins\**" />
<Content Include="Plugins\**" CopyToPublishDirectory="PreserveNewest" Exclude="Plugins\**\*.config;Plugins\**\*.cshtml;Plugins\**\*.json" />
<Content Include="Themes\**" CopyToPublishDirectory="PreserveNewest" Exclude="Themes\**\*.config;Themes\**\*.cshtml;Themes\**\*.json" />
<!-- We copy the \Logs directory -->
<Content Include="Logs\**" CopyToPublishDirectory="PreserveNewest" />
<None Update="Areas\Admin\sitemap.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Plugins\" />
</ItemGroup>
<!-- This target execute after "Build" target.
We use it to clean up folder with plugins from unnecessary and obsolete libraries. -->
<Target Name="NopTarget" AfterTargets="Build">
<ItemGroup>
<!-- Get plugin description files to get plugin paths -->
<PluginsDescription Include="$(MSBuildProjectDirectory)\Plugins\**\plugin.json;" />
<!-- Get paths for all plugins -->
<PluginsFolders Include="#(PluginsDescription->'%(relativedir)')" />
<!-- Get all the libraries from the shadow copy folder to remove them,
because depending on the settings, this may not happen when the application is starting,
but this can lead to unpredictable results during debugging of the project. -->
<ShadowCopiesLibraries Include="$(MSBuildProjectDirectory)\Plugins\bin\*.*" Exclude="$(MSBuildProjectDirectory)\Plugins\bin\placeholder.txt" />
</ItemGroup>
<PropertyGroup>
<PluginsFolders>#(PluginsFolders)</PluginsFolders>
</PropertyGroup>
<!-- Delete libraries from the shadow copy folder -->
<Delete Files="#(ShadowCopiesLibraries)" />
<!-- When .NET Core builds a project, it copies all referenced libraries to the output folder.
For plugins it creates too many unnecessary files that just take up space.
At the moment you can't disable this behavior. That's why we have to manually delete all unnecessary libraries from plugin output directories. -->
<MSBuild Projects="$(MSBuildProjectDirectory)\..\..\Build\ClearPluginAssemblies.proj" Properties="PluginPath=$(PluginsFolders)" Targets="NopClear" />
</Target>
<PropertyGroup>
<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>
</PropertyGroup>
</Project>
This looks more like a dotnet publish issue then an actually issue with docker.
If you search on the actual error that dotnet cli shows MSB3073, you can find that it's often related to post build events.
In many cases, the path to each folder/assembly referenced in the post build event is not correct.
If we look closer at where we are when the publish command is executed
WORKDIR /app/Presentation/MyProject.Web
And then for example look at the PluginPath in the error message
..PluginPath=/app/Presentation/MyProject.Web/Plugins/DiscountRules.CustomerRoles/;..
You can then see that the path is not inline from where the command is executed.
One solutions would be to add absolute path or make them relative from where the publish command is executed. You could also specify a specific post/pre-events for each configuration, here's an answer regarding publish-events

Asp.net core 2 - Files are not published

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>

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>

Why does my MSBuild Exec Command Fail?

I have a pretty simple setup for this application I'm using to test something:
-Solution in VS
-Project for cs code (named Client)
-Project for Thrift files( named Thrift)
-Folder for Erlang Code(Doesn't show up in VS)
The idea is I'll build the Thrift project, have it generate the code for both languages, copy the generated erlang code to the correct directory (with MSBuild, but first things first), and include the generated csharp code in the Thrift project. To do this I have the following "BeforeBuild" target:
<Target Name="BeforeBuild">
<Exec Command="cmd /c "C:\Windows\System32\thrift.exe" -gen erl -gen csharp *.thrift" />
<ItemGroup>
<CSFile Include="$(SolutionDir)gen-csharp\*" />
</ItemGroup>
I get the error "'C:\Windows\System32\thrift.exe' is not recognized as an internal or external command, operable program or batch file".
I tried Command="thrift ..." since thrift is in my PATH, but found out that MSBuild doesn't find programs from the PATH variable.
Note: Using the command without "cmd /c" results in the same error message, but with a different error code (9001, because MSBuild is unable to find the file, instead of "cmd /c" failing to find the file).
Edit: For posterity, the working result is:
<Project>
...
(Auto generated data)
...
<PropertyGroup>
<CleanDependsOn>
$(CleanDependsOn);
CleanThriftGen;
</CleanDependsOn>
<ErlangProjectSrcDir>$(SolutionDir)Server\src\gen\</ErlangProjectSrcDir>
<GenCSharpDir>gen-csharp\</GenCSharpDir>
<GenErlDir>gen-erl\</GenErlDir>
<ThriftDir>C:\thrift\</ThriftDir>
</PropertyGroup>
<Target Name="BeforeBuild">
<Exec Command="$(ThriftDir)thrift.exe -gen erl -gen csharp *.thrift" />
</Target>
<Target Name="AfterBuild">
<ItemGroup>
<ErlangSrcGroup Include="$(GenErlDir)**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(ErlangSrcGroup)" DestinationFiles="$(ErlangProjectSrcDir)%(RecursiveDir)%(Filename)%(Extension)" ContinueOnError="false" />
</Target>
<Target Name="CleanThriftGen">
<RemoveDir Directories="$(ErlangProjectSrcDir)" />
<RemoveDir Directories="$(GenCSharpDir)" />
<RemoveDir Directories="$(GenErlDir)" />
</Target>
<ItemGroup>
<CSharpGenGroup Include="$(GenCSharpDir)**\*.*" />
</ItemGroup>
Found the majority of my answer, in my haste I had stuck the executable in the first directory I knew would already be in my path, System32. Moving it to another folder fixes the error when running the tool directly from VS (vs cmd /c).
But I'm still not clear on what caused this. I don't know why cmd /c would be unable to find it when a command prompt with normal privileges could, and I don't know why VS couldn't find it.
As a test I gave the new folder I placed it in permissions to require administrative privileges to write to, same as System32, but VS is still able to run it from there.

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