【问题标题】:Visual Studio 2017 csproj .NET Core build - views not being copied correctlyVisual Studio 2017 csproj .NET Core 构建 - 未正确复制视图
【发布时间】:2017-08-12 02:00:05
【问题描述】:

我有一个在 .NET Core 中运行的项目,我使用 VS2017 作为 IDE。

当我通过 Visual Studio 2017 构建项目时,它不会自动将 Views 文件夹和 wwwroot 文件夹添加到 [projectRoot]/bin/Debug/netcoreapp1.1/win10-x64(BuildDir) 的输出中。这意味着如果我尝试直接从 bin 文件夹中创建的 .exe file 运行我的网站,我会收到缺少 viewswwwroot 的错误。如果我手动将这些文件夹复制到 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 文件),上述所有方法都可以正常工作。我只有一个项目运行器,我希望能够指向我的网站可执行文件的调试版本,因为与仅使用 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>      

【问题讨论】:

  • 我已将我的答案更新为允许我们从 any 位置运行输出 EXE 的答案。请让我知道它是否适合您。
  • 在您的更新中,您会收到错误消息,因为您没有使用 Shaun 示例中包含的 &lt;EnableDefaultContentItems&gt;false&lt;/EnableDefaultContentItems&gt;

标签: visual-studio msbuild asp.net-core-mvc .net-core visual-studio-2017


【解决方案1】:

我所解释的挑战是运行dotnet build 并能够从任何地方执行已编译的EXE。答案需要两个步骤:

  1. 将所需内容复制到 bin,然后
  2. 相对于 bin 设置 ContentRoot 和 WebRoot。

首先,修改csproj,将需要的内容复制到bin。开箱即用,dotnet build 不会将 Views、appsettings.json 或 wwwroot 复制到 bin。所以,我们需要明确指定CopyToOutputDirectory;为此,我们还需要将EnableDefaultContentItems 设置为false,否则我们的显式设置将复制默认的内容项设置。

其次,修改 Program.cs 以指定新的 ContentRoot 和 WebRoot。开箱即用,Program.cs 设置 UseContentRoot(Directory.GetCurrentDirectory())。对于我们的情况有问题的是,当前目录是 我们从中运行可执行文件的目录。因此,如果我们从桌面上的命令行运行 EXE,那么当前目录将是 C:/Users/MyUser/Desktop。该应用将找不到 View、appsettings.json 和其他内容。

以下是我用来应对挑战的一些工作步骤,正如我所解释的那样。

工作步​​骤

  1. cd C:\temp
  2. dotnet new mvc
  3. 使用“工作 csproj”XML 更新 temp.csproj。
  4. 使用“Working Program.cs”代码更新 Program.cs。
  5. dotnet restore
  6. dotnet build
  7. cd ..
  8. 任何地方,运行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>  

工作程序.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();
    }
}

【讨论】:

  • 我已经定义了一个,但它不起作用。我也尝试创建一个新项目。它也不起作用(当我添加您定义的属性组时)。你能在编辑中看到我的.csproj 文件吗?
  • 这是正确的。我再次更新了我的问题以概述错误。
  • PreserveCompilationContext 已通过 Microsoft.NET.Sdk.Web 设置
  • 我没有在 MSBuild 上导出,但看起来没问题。我实际上并不同意 OP 这里存在问题。 BuildingPublishing 是两个谨慎的步骤 - 这是设计使然。您不希望每次需要编译 C# 时都复制所有静态资产。
  • @ChadT 公平点。 OP 在某些方面是在询问如何射击自己的脚。
【解决方案2】:

我已将此作为问题发布到 GitHub 上的 ASP.NET Core 存储库: https://github.com/aspnet/Home/issues/2897

虽然接受的答案有效,但感觉有点像 hack。

它也有问题。当需要复制的文件很多时,构建过程很慢,并且构建过程不会删除已删除的文件。

接受的答案也是对 EnableDefaultContentItems 设置的滥用。

因此,虽然我很高兴有一个短期的解决方案,但需要寻求问题的长期解决方案。

希望我在 GitHub 上提出的问题能够以某种方式实现更持久的解决方案。

【讨论】:

    猜你喜欢
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多