Visual Studio 2017 csproj .NET Core 构建 - 未正确复制视图
Visual Studio 2017 csproj .NET Core build - views not being copied correctly
我在 .NET Core 中有一个项目 运行ning,我正在使用 VS2017 作为 IDE。
当我通过 Visual Studio 2017 构建我的项目时,它不会自动将 Views 文件夹和 wwwroot 文件夹添加到 [projectRoot]/bin/Debug/netcoreapp1.1/win10-x64
(BuildDir
) 的输出中。这意味着如果我尝试直接从 bin 文件夹中创建的 .exe file
访问我的网站 运行,我会收到缺少 views
和 wwwroot
的错误。如果我手动将这些文件夹复制到 BuildDir
,则视图会正确加载。
我可以在我的 .csproj 文件中使用以下内容进行设置:
<Content Update="Views\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
然后 Views
工作,但现在我的布局文件没有被编译,所以我得到以下信息:
<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>
这意味着我的根文件夹没有被正确定位。而且有点告诉我,只是将文件复制到输出目录是不正确的。
如果我发布我的应用程序(也没有添加到 .csproj 文件),以上所有内容都有效。我只有一个项目 运行ner,我希望能够指向我的网站可执行文件的调试版本,因为与仅使用 VS2017 构建项目相比,很容易忘记进行发布。
我只是不知道从哪里开始,如果有任何帮助,我们将不胜感激?
编辑:
添加了精简版的 csproj(不起作用):
<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>
还尝试使用 dotnet new mvc
创建一个新项目
而且它也不起作用。
我的 dotnet core cli 版本是 [1.0.1]。
编辑:
我按照您概述的步骤进行了操作。我还尝试使用 dotnet new mvc
创建一个新项目并按照您的步骤操作。两者都给了我同样的错误。无法找到 appsettings.json
。如果我然后将 propertygroup
添加到 .csproj。这告诉 msbuild 将 appsettings.json 和 web.config 复制到输出
<ItemGroup>
<Content Update="appsettings.json;web.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
然后我可以通过 exe 启动程序,但是当我访问索引时,当我尝试访问其中一个视图时,它会给我:
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
更新:
Shaun Lutins 的回答似乎对我有用。都有构建和发布选项。唯一的问题是我遇到了一个错误:
Duplicate 'Content' items were included. The .NET SDK includes 'Content' items from your project directory by default.
但已通过更改以下内容解决:
<ItemGroup>
<Content Include="appsettings.json" CopyToOutputDirectory="Always" />
<Content Include="Views\**\*" CopyToOutputDirectory="Always" />
<Content Include="wwwroot\**\*" CopyToOutputDirectory="Always" />
</ItemGroup>
到
<ItemGroup>
<Content Update="appsettings.json;web.config" CopyToOutputDirectory="PreserveNewest"/>
<Content Update="Views\**\*" CopyToOutputDirectory="PreserveNewest" />
<Content Update="wwwroot\**\*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
我所解释的挑战是到运行dotnet build
并且能够从任何地方执行编译后的EXE。答案需要两个步骤:
- 将需要的内容复制到bin,
- 设置相对于 bin 的 ContentRoot 和 WebRoot。
首先,修改csproj,将需要的内容复制到bin中。开箱即用,dotnet build
不会将视图、appsettings.json 或 wwwroot 复制到 bin。所以,我们需要明确指定CopyToOutputDirectory
;为此,我们还需要将 EnableDefaultContentItems
设置为 false,否则我们的显式设置将复制默认内容项设置。
其次,修改Program.cs以指定新的ContentRoot 和WebRoot。开箱即用,Program.cs
设置 UseContentRoot(Directory.GetCurrentDirectory())
。对于我们的情况来说有问题的是,当前目录是 我们从中 运行 可执行文件 的目录。因此,如果我们从桌面的命令行 运行 EXE,则当前目录将为 C:/Users/MyUser/Desktop
。该应用程序将找不到视图、appsettings.json 和其他内容。
以下是我用来应对挑战的一些工作步骤,正如我所解释的那样。
工作步骤
cd C:\temp
dotnet new mvc
- 将 temp.csproj 更新为 "Working csproj" XML。
- 用 "Working Program.cs" 代码更新 Program.cs。
dotnet restore
dotnet build
cd ..
- 来自任何地方,运行
C:\temp\bin\Debug\netcoreapp1.0\win10-x64\temp.exe
工作中的 csproj
<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>
工作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();
}
}
我已将此作为问题发布到 GitHub 上的 ASP.NET 核心存储库:
https://github.com/aspnet/Home/issues/2897
虽然接受的答案有效,但感觉有点像黑客。
它也有问题。当有很多文件要复制时构建过程很慢,并且构建过程不会删除已删除的文件。
接受的答案也是对 EnableDefaultContentItems 设置的误用。
因此,尽管我很高兴有 short-term 解决方案,但仍需要寻求 long-term 解决问题的方法。
希望我在 GitHub 提出的问题能以某种方式朝着更持久的解决方案迈进。
我在 .NET Core 中有一个项目 运行ning,我正在使用 VS2017 作为 IDE。
当我通过 Visual Studio 2017 构建我的项目时,它不会自动将 Views 文件夹和 wwwroot 文件夹添加到 [projectRoot]/bin/Debug/netcoreapp1.1/win10-x64
(BuildDir
) 的输出中。这意味着如果我尝试直接从 bin 文件夹中创建的 .exe file
访问我的网站 运行,我会收到缺少 views
和 wwwroot
的错误。如果我手动将这些文件夹复制到 BuildDir
,则视图会正确加载。
我可以在我的 .csproj 文件中使用以下内容进行设置:
<Content Update="Views\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
然后 Views
工作,但现在我的布局文件没有被编译,所以我得到以下信息:
<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>
这意味着我的根文件夹没有被正确定位。而且有点告诉我,只是将文件复制到输出目录是不正确的。
如果我发布我的应用程序(也没有添加到 .csproj 文件),以上所有内容都有效。我只有一个项目 运行ner,我希望能够指向我的网站可执行文件的调试版本,因为与仅使用 VS2017 构建项目相比,很容易忘记进行发布。
我只是不知道从哪里开始,如果有任何帮助,我们将不胜感激?
编辑:
添加了精简版的 csproj(不起作用):
<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>
还尝试使用 dotnet new mvc
而且它也不起作用。
我的 dotnet core cli 版本是 [1.0.1]。
编辑:
我按照您概述的步骤进行了操作。我还尝试使用 dotnet new mvc
创建一个新项目并按照您的步骤操作。两者都给了我同样的错误。无法找到 appsettings.json
。如果我然后将 propertygroup
添加到 .csproj。这告诉 msbuild 将 appsettings.json 和 web.config 复制到输出
<ItemGroup>
<Content Update="appsettings.json;web.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
然后我可以通过 exe 启动程序,但是当我访问索引时,当我尝试访问其中一个视图时,它会给我:
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
更新:
Shaun Lutins 的回答似乎对我有用。都有构建和发布选项。唯一的问题是我遇到了一个错误:
Duplicate 'Content' items were included. The .NET SDK includes 'Content' items from your project directory by default.
但已通过更改以下内容解决:
<ItemGroup>
<Content Include="appsettings.json" CopyToOutputDirectory="Always" />
<Content Include="Views\**\*" CopyToOutputDirectory="Always" />
<Content Include="wwwroot\**\*" CopyToOutputDirectory="Always" />
</ItemGroup>
到
<ItemGroup>
<Content Update="appsettings.json;web.config" CopyToOutputDirectory="PreserveNewest"/>
<Content Update="Views\**\*" CopyToOutputDirectory="PreserveNewest" />
<Content Update="wwwroot\**\*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
我所解释的挑战是到运行dotnet build
并且能够从任何地方执行编译后的EXE。答案需要两个步骤:
- 将需要的内容复制到bin,
- 设置相对于 bin 的 ContentRoot 和 WebRoot。
首先,修改csproj,将需要的内容复制到bin中。开箱即用,dotnet build
不会将视图、appsettings.json 或 wwwroot 复制到 bin。所以,我们需要明确指定CopyToOutputDirectory
;为此,我们还需要将 EnableDefaultContentItems
设置为 false,否则我们的显式设置将复制默认内容项设置。
其次,修改Program.cs以指定新的ContentRoot 和WebRoot。开箱即用,Program.cs
设置 UseContentRoot(Directory.GetCurrentDirectory())
。对于我们的情况来说有问题的是,当前目录是 我们从中 运行 可执行文件 的目录。因此,如果我们从桌面的命令行 运行 EXE,则当前目录将为 C:/Users/MyUser/Desktop
。该应用程序将找不到视图、appsettings.json 和其他内容。
以下是我用来应对挑战的一些工作步骤,正如我所解释的那样。
工作步骤
cd C:\temp
dotnet new mvc
- 将 temp.csproj 更新为 "Working csproj" XML。
- 用 "Working Program.cs" 代码更新 Program.cs。
dotnet restore
dotnet build
cd ..
- 来自任何地方,运行
C:\temp\bin\Debug\netcoreapp1.0\win10-x64\temp.exe
工作中的 csproj
<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>
工作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();
}
}
我已将此作为问题发布到 GitHub 上的 ASP.NET 核心存储库: https://github.com/aspnet/Home/issues/2897
虽然接受的答案有效,但感觉有点像黑客。
它也有问题。当有很多文件要复制时构建过程很慢,并且构建过程不会删除已删除的文件。
接受的答案也是对 EnableDefaultContentItems 设置的误用。
因此,尽管我很高兴有 short-term 解决方案,但仍需要寻求 long-term 解决问题的方法。
希望我在 GitHub 提出的问题能以某种方式朝着更持久的解决方案迈进。