Visual Studio 2017 csproj.NET Core build - views are not copied correctly

I have a project running in .NET Core and I am using VS2017 as an IDE.

When I create my project through Visual Studio 2017, it does not automatically add the Views folder and wwwroot folder to the output in [projectRoot]/bin/Debug/netcoreapp1.1/win10-x64 ( BuildDir ). This means that if I try to start my site directly from the .exe file created in the bin folder, I get an error with missing views and wwwroot . If I manually copy these folders to BuildDir , then the views will load correctly.

I can configure this in my .csproj file with the following:

 <Content Update="Views\**"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> 

And then views works, but now my layout file does not compile, so I get the following:

 <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"] - FirstAgenda</title> <environment names="Development"> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" /> <link rel="stylesheet" href="~/css/site.css"/> <link rel="stylesheet" href="~/css/overwrite.css" asp-append-version="true" /> </environment> <environment names="Staging,Production"> <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css" asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css" asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" /> <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" /> <link rel="stylesheet" href="~/css/overwrite.css" asp-append-version="true" /> </environment> </head> 

This means that my root folder is not configured correctly. And also, it seems to me, just copying files to the output directory is wrong.

All of the above works if I publish my application (also without adding the .csproj file). I just have a project runner who would like to point to the Debug version of my websiteโ€™s executable, because itโ€™s very easy to forget to publish compared to just creating a project using VS2017.

I just don't know where to go from this and any help would be appreciated?

EDIT:

Added a stripped down version of csproj (which does not work):

 <Project ToolsVersion="15.0" Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp1.1</TargetFramework> <PreserveCompilationContext>true</PreserveCompilationContext> <RuntimeIdentifier>win10-x64</RuntimeIdentifier> </PropertyGroup> <ItemGroup> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.0.0" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="1.1.1" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" /> <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" /> <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" /> <PackageReference Include="Microsoft.AspNetCore.Routing" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="1.0.1" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.1.0-preview4-final" /> <PackageReference Include="IdentityServer4" Version="1.3.1" /> <PackageReference Include="IdentityServer4.AspNetIdentity" Version="1.0.0" /> <PackageReference Include="IdentityServer4.EntityFramework" Version="1.0.0" /> <PackageReference Include="OctoPack" Version="3.5.2" /> <PackageReference Include="Serilog.Extensions.Logging.File" Version="1.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="1.1.0" /> </ItemGroup> <ItemGroup> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet"> <Version>1.1.0-preview4-final</Version> </DotNetCliToolReference> <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools"> <Version>1.0.0-msbuild1-final</Version> </DotNetCliToolReference> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools"> <Version>1.0.0-msbuild1-final</Version> </DotNetCliToolReference> </ItemGroup> <ItemGroup> <ProjectReference Include="..\[OWNPROJECT]" /> <ProjectReference Include="..\[OWNPROJECT1]" /> </ItemGroup> </Project> 

Also tried creating a new project using dotnet new mvc

And it doesn't work either.

My version of clot for the dotnet kernel is [1.0.1].

EDIT:

I followed the steps you described. I also tried creating a new project using dotnet new mvc and followed your steps. Both gave me the same mistakes. He could not find appsettings.json . If I then add a propertygroup to .csproj. This tells msbuild to copy appsettings.json and web.config to the output

 <ItemGroup> <Content Update="appsettings.json;web.config"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup> 

Then I can run the program through exe, but when I access the index, then when I try to access one of the views that it gives me:

 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0] An unhandled exception has occurred while executing the request System.InvalidOperationException: The view 'Index' was not found. The following locations were searched: /Views/Home/Index.cshtml /Views/Shared/Index.cshtml 

UPDATE:

Shaun Lutins answer seems to work for me. Both assembly and publication options. The only problem was that I was getting an error:

Duplicate 'Content' items were included. The .NET SDK includes 'Content' items from your project directory by default.

But this was resolved by changing the following:

 <ItemGroup> <Content Include="appsettings.json" CopyToOutputDirectory="Always" /> <Content Include="Views\**\*" CopyToOutputDirectory="Always" /> <Content Include="wwwroot\**\*" CopyToOutputDirectory="Always" /> </ItemGroup> 

to

 <ItemGroup> <Content Update="appsettings.json;web.config" CopyToOutputDirectory="PreserveNewest"/> <Content Update="Views\**\*" CopyToOutputDirectory="PreserveNewest" /> <Content Update="wwwroot\**\*" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup> 
+5
source share
2 answers

The task that I interpreted is to do dotnet build and be able to execute the compiled EXE from anywhere. The answer requires two steps:

  • copy the required content to the basket and
  • set ContentRoot and WebRoot relative to the bin.

First modify the csproj file to copy the desired content to the trash. Out of the box, dotnet build does not copy Views, appsettings.json or wwwroot to the trash. So, we must explicitly specify CopyToOutputDirectory ; and for this we also need to set EnableDefaultContentItems to false, otherwise our explicit settings will duplicate the default content content settings.

Second, modify Program.cs to specify a new ContentRoot and WebRoot. Out of the box, Program.cs sets UseContentRoot(Directory.GetCurrentDirectory()) . Problem for our situation, the current directory is the directory from which we run the executable file. So, if we run the EXE from the command line on our desktop, then the current directory will be C:/Users/MyUser/Desktop . The application will not find Views, appsettings.json and other content.

Here are some work steps that I used to solve this problem as I interpreted it.

Work steps

  • cd C:\temp
  • dotnet new mvc
  • Update temp.csproj with the XML code "Working csproj".
  • Update Program.cs with the code "Working Program.cs".
  • dotnet restore
  • dotnet build
  • cd ..
  • From anywhere, run C:\temp\bin\Debug\netcoreapp1.0\win10-x64\temp.exe

Csproj work

 <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp1.0</TargetFramework> <RuntimeIdentifier>win10-x64</RuntimeIdentifier> <OutputType>exe</OutputType> <EnableDefaultContentItems>false</EnableDefaultContentItems> </PropertyGroup> <ItemGroup> <Content Include="appsettings.json" CopyToOutputDirectory="Always" /> <Content Include="Views\**\*" CopyToOutputDirectory="Always" /> <Content Include="wwwroot\**\*" CopyToOutputDirectory="Always" /> </ItemGroup> <ItemGroup> <!-- Package references omitted for clarity --> </ItemGroup> </Project> 

Work program .cs

 public class Program { public static void Main(string[] args) { // C:\temp\bin\Debug\netcoreapp1.0\win10-x64\temp.dll var assemblyFilePath = System.Reflection.Assembly.GetEntryAssembly().Location; // C:\temp\bin\Debug\netcoreapp1.0\win10-x64\ var binDirectory = System.IO.Path.GetDirectoryName(assemblyFilePath); Console.WriteLine(assemblyFilePath); Console.WriteLine(binDirectory); var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(binDirectory) // <-- .UseWebRoot("wwwroot") // <-- .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); } } 
+3
source

I posted this as a problem for replicating ASP.NET Core on GitHub: https://github.com/aspnet/Home/issues/2897

As long as the accepted answer works, it looks a bit like a hack.

There are problems with this. The build process is slow when there are many files to copy, and the build process does not delete files that have been deleted.

The accepted answer is also a misuse of the EnableDefaultContentItems parameter.

Therefore, when I am glad that a short-term solution exists, a long-term solution to the problem must be sought.

I would like to hope that the problem that I raised in GitHub will work towards a more efficient solution.

0
source

Source: https://habr.com/ru/post/1265711/


All Articles