.NET Core 的 csproj 格式的新增内容Additions to the csproj format for .NET Core

本文内容

本文档概述了作为从 project.json 移动到 csprojMSBuild 的一部分,添加到项目文件的更改。有关常规项目文件的语法和引用的详细信息,请参阅 MSBuild 项目文件文档。

隐式包引用Implicit package references

基于项目文件的 <TargetFramework><TargetFrameworks> 属性中指定的目标框架对元包进行隐式引用。如果指定了 <TargetFramework>,则忽略 <TargetFrameworks>,而与顺序无关。有关详细信息,请参阅包、元包和框架

  1. <PropertyGroup>
  2. <TargetFramework>netcoreapp2.1</TargetFramework>
  3. </PropertyGroup>
  1. <PropertyGroup>
  2. <TargetFrameworks>netcoreapp2.1;net462</TargetFrameworks>
  3. </PropertyGroup>

建议Recommendations

由于隐式引用了 Microsoft.NETCore.AppNETStandard.Library 元包,以下是建议的最佳做法:

  • 面向 .NET Core 或 .NET Standard 时,绝不通过项目文件中的 <PackageReference> 项,对 Microsoft.NETCore.AppNETStandard.Library 元包进行显式引用。
  • 面向 .NET Core 时,如果需要特定版本的运行时,应使用项目中的 <RuntimeFrameworkVersion> 属性(例如,1.0.4),而不是引用元包。
    • 例如,如果使用独立部署且需要 1.0.0 LTS 运行时的特定修补程序版本,可能会发生这种情况。
  • 面向 .NET Standard 时,如果需要特定版本的 NETStandard.Library 元包,可以使用 <NetStandardImplicitPackageVersion> 属性并设置所需版本。
  • 请勿在 .NET Framework 项目中显式添加或更新对 Microsoft.NETCore.AppNETStandard.Library 元包的引用。使用基于 .NET Standard 的 NuGet 包时,如果需要任意版本的 NETStandard.Library,NuGet 可自动安装该版本。

一些包引用的隐式版本Implicit version for some package references

<PackageReference> 的大多数用法都要求设置 Version 属性,用于指定要使用的 NuGet 包版本。不过,如果使用的是 .NET Core 2.1 或 2.2,且引用 Microsoft.AspNetCore.AppMicrosoft.AspNetCore.All,就没有必要设置此属性。.NET Core SDK 可自动选择应使用的包版本。

建议Recommendation

引用 Microsoft.AspNetCore.AppMicrosoft.AspNetCore.All 包时,不要指定包版本。如果你指定版本,SDK 可能会生成警告 NETSDK1071。若要修复此警告,请删除包版本,如下面的示例所示:

  1. <ItemGroup>
  2. <PackageReference Include="Microsoft.AspNetCore.App" />
  3. </ItemGroup>

已知问题:.NET Core 2.1 SDK 只在项目还使用 Microsoft.NET.Sdk.Web 时才支持这种语法。 .NET Core 2.2 SDK 中解决了此问题。

这些对 ASP.NET Core 元包的引用行为与大多数普通 NuGet 包略有不同。使用这些元包的应用的框架依赖部署自动使用 ASP.NET Core 共享框架。使用元包时,引用的 ASP.NET Core NuGet 包中的任何资产都不会 与应用一起部署。也就是说,ASP.NET Core 共享框架包含这些资产。共享框架中的资产更适合目标平台,旨在缩短应用启动时间。若要详细了解共享框架,请参阅 .NET Core 分发打包

如果指定 版本,这会被视为框架依赖部署的 ASP.NET Core 共享框架的最低 版本,并被视为独立式部署的确切 版本。这可能会导致以下后果:

  • 如果服务器上安装的 ASP.NET Core 版本低于 PackageReference 中指定的版本,.NET Core 进程便会无法启动。元包更新通常先可用于 NuGet.org,再可用于托管环境(如 Azure)。将 PackageReference 中的版本更新为 ASP.NET Core 可能会导致部署的应用失败。
  • 如果应用部署为独立式部署,应用可能不包含 .NET Core 的最新安全更新程序。如果未指定版本,SDK 可以自动在独立式部署中包含 ASP.NET Core 的最新版本。

.NET Core 项目中默认包含的编译项Default compilation includes in .NET Core projects

已通过移动到最新 SDK 版本中的 csproj 格式,将默认的编译项和嵌入资源的包含项和排除项移至 SDK 属性文件。这意味着不需要再在项目文件中指定这些项。

执行此操作的主要目的是减少项目文件中的混杂。SDK 中的默认设置应涵盖最常见的用例,由此便无需在创建的每个项目中重复这些设置。这可使项目文件更小,更易于理解和进行手动编辑(如果需要)。

下表显示同时在 SDK 中包含和排除的元素和 globs):

元素包含 glob排除 glob删除 glob
Compile/*.cs(或其他语言扩展名)/.user; **/.proj; **/.sln; /*.vssscc不可用
EmbeddedResource/.resx**/.user; /.proj; /.sln; **/.vssscc不可用
None/*/.user; **/.proj; **/.sln; /*.vssscc/.cs; **/.resx

备注

排除 glob 始终排除 ./bin./obj 文件夹,它们分别由 MSBuild 属性 $(BaseOutputPath)$(BaseIntermediateOutputPath) 表示。总体上来说,所有排除都由 $(DefaultItemExcludes) 表示。

如果项目中有 glob,却又尝试使用最新的 SDK 生成它,则将收到以下错误:

包含重复的编译项。 默认情况下,.NET SDK 包括项目目录中的编译项。 可从项目文件中删除这些项,或如果想要在项目文件中显式包括它们,则将“EnableDefaultCompileItems”属性设为“false”。

要解决此错误,可以删除与前表中所列项匹配的显式 Compile 项,也可以将 <EnableDefaultCompileItems> 属性设置为 false,如下所示:

  1. <PropertyGroup>
  2. <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
  3. </PropertyGroup>

将此属性设置为 false 将禁用隐式包含,并还原到以前 SDK 的行为,在这种情况下,必须在项目中指定默认 glob。

此更改不会修改其他包含项的主要机制。但是,如果要指定(例如,指定某些文件通过应用发布),仍可以使用 csproj 中相应的已知机制来实现(例如,<Content> 元素)。

<EnableDefaultCompileItems> 仅禁用 Compile glob,但不会影响其他 glob(如隐式 None glob),这也适用于 .cs 项。因此,解决方案资源管理器 继续显示在项目中作为 None 项的 .cs 项。以类似的方式,可以将 <EnableDefaultNoneItems> 设置为 false 以禁用隐式 None glob,如下所示:

  1. <PropertyGroup>
  2. <EnableDefaultNoneItems>false</EnableDefaultNoneItems>
  3. </PropertyGroup>

要禁用所有隐式 glob ,可将 <EnableDefaultItems> 属性设置为 false,如以下示例所示:

  1. <PropertyGroup>
  2. <EnableDefaultItems>false</EnableDefaultItems>
  3. </PropertyGroup>

如何像 MSBuild 一样查看整个项目How to see the whole project as MSBuild sees it

虽然这些 csproj 更改极大地简化了项目文件,但建议查看完全展开的项目,就像 MSBuild 查看添加了 SDK 及其目标的项目一样。使用 dotnet msbuild 命令的 /pp 开关预处理项目,显示导入的文件、文件源及其在生成中的参与情况,而无需实际生成项目:

dotnet msbuild -pp:fullproject.xml

如果项目有多个目标框架,命令结果应仅侧重于框架之一,具体方法为将相应框架指定为 MSBuild 属性:

dotnet msbuild -p:TargetFramework=netcoreapp2.0 -pp:fullproject.xml

新增内容Additions

Sdk 特性Sdk attribute

.csproj 文件的根 <Project> 元素具有名为 Sdk 的新特性 。Sdk 指定项目将使用的 SDK。分层文档中所述,SDK 是一组可生成 .NET Core 代码的 MSBuild 任务目标.NET Core 可使用以下 SDK:

  • ID 为 Microsoft.NET.Sdk 的 .NET Core SDK
  • ID 为 Microsoft.NET.Sdk.Web 的 .NET Core Web SDK
  • ID 为 Microsoft.NET.Sdk.Razor 的 .NET Core Razor 类库 SDK
  • ID 为 Microsoft.NET.Sdk.Worker 的 .NET Core Worker Service(自 .NET Core 3.0 起)
  • ID 为 Microsoft.NET.Sdk.WindowsDesktop 的 .NET Core WinForms 和 WPF(自 .NET Core 3.0 起)需要在 <Project> 元素上将 Sdk 属性设置为这两个 ID 之一,以使用 .NET Core 工具和生成代码。

PackageReferencePackageReference

<PackageReference> 项元素指定项目中的 NuGet 依赖项Include 属性指定包 ID。

  1. <PackageReference Include="<package-id>" Version="" PrivateAssets="" IncludeAssets="" ExcludeAssets="" />

VersionVersion

所需的 Version 属性指定要还原的包的版本。此属性遵循 NuGet 版本控制方案规则。默认行为是精确的版本匹配。例如,指定 Version="1.2.3" 等效于包的 1.2.3 版本的 NuGet 表示法 [1.2.3]

IncludeAssets、ExcludeAssets 和 PrivateAssetsIncludeAssets, ExcludeAssets and PrivateAssets

IncludeAssets 属性指定应使用 <PackageReference> 指定的包中的哪些资产。默认情况下,包含所有包资产。

ExcludeAssets 属性指定不应使用 <PackageReference> 指定的包中的哪些资产。

PrivateAssets 属性指定应使用 <PackageReference> 指定的包中的哪些资产,但不得将这些资产传递到下一个项目。不存在此属性时,AnalyzersBuildContentFiles 资产默认为私有。

备注

PrivateAssets 等效于 project.json/xproj SuppressParent 元素。

这些属性可以包含以下一个或多个项,如果列出多个项,则用分号 ; 字符进行分隔:

  • Compile - 可对 lib 文件夹内容进行编译。
  • Runtime - 分发运行时文件夹内容。
  • ContentFiles - 使用 contentfiles 文件夹的内容。
  • Build - 使用生成文件夹中的属性/目标。
  • Native - 将本机资产内容复制到运行时输出文件夹。
  • Analyzers - 使用分析器。此属性也可以包含:

  • None - 不使用任何资产。

  • All - 使用所有资产。

DotNetCliToolReferenceDotNetCliToolReference

<DotNetCliToolReference> 项元素指定用户想要在项目的上下文中还原的 CLI 工具。project.json 中,它可以替换 tools 节点。

  1. <DotNetCliToolReference Include="<package-id>" Version="" />

VersionVersion

Version 指定要还原的包的版本。此属性遵循 NuGet 版本控制方案规则。默认行为是精确的版本匹配。例如,指定 Version="1.2.3" 等效于包的 1.2.3 版本的 NuGet 表示法 [1.2.3]

RuntimeIdentifiersRuntimeIdentifiers

<RuntimeIdentifiers> 属性元素可用于指定项目的运行时标识符 (RID) 的列表(以分号分隔)。RID 允许发布独立部署。

  1. <RuntimeIdentifiers>win10-x64;osx.10.11-x64;ubuntu.16.04-x64</RuntimeIdentifiers>

RuntimeIdentifierRuntimeIdentifier

<RuntimeIdentifier> 属性元素可用于指定项目的唯一运行时标识符 (RID)RID 支持发布独立部署。

  1. <RuntimeIdentifier>ubuntu.16.04-x64</RuntimeIdentifier>

如果需要为多个运行时发布,请使用 <RuntimeIdentifiers>(复数)。如果只需要单个运行时,<RuntimeIdentifier> 可以进行较快的生成。

PackageTargetFallbackPackageTargetFallback

<PackageTargetFallback> 属性元素可用于指定要在还原包时使用的一组兼容目标。旨在允许使用 dotnet TxM(目标 x 名字对象) 的包处理未声明 dotnet TxM 的包。如果项目使用 dotnet TxM,那么所依赖的所有包也必须有 dotnet TxM,除非将 <PackageTargetFallback> 添加到项目中,以允许非 dotnet 平台与 dotnet 兼容。

以下示例展示了项目中所有目标的回退:

  1. <PackageTargetFallback>
  2. $(PackageTargetFallback);portable-net45+win8+wpa81+wp8
  3. </PackageTargetFallback >

以下示例仅指定了 netcoreapp2.1 目标的回退:

  1. <PackageTargetFallback Condition="'$(TargetFramework)'=='netcoreapp2.1'">
  2. $(PackageTargetFallback);portable-net45+win8+wpa81+wp8
  3. </PackageTargetFallback >

NugetMetadataPropertiesNuGet metadata properties

迁移到 MSBuild 后,我们已将在打包 NuGet 包时使用的输入元数据从 project.json 移到 .csproj 文件中 。输入为 MSBuild 属性,因此它们必须转到 <PropertyGroup> 组中。下面列出了在使用 dotnet pack 命令或属于 SDK 的 Pack MSBuild 目标时,用作打包进程的输入的属性。

IsPackableIsPackable

一个指定能否打包项目的布尔值。默认值为 true

PackageVersionPackageVersion

指定生成的包所具有的版本。接受所有形式的 NuGet 版本字符串。默认为值 $(Version),即项目中 Version 属性的值。

PackageIdPackageId

指定生成的包的名称。如果未指定,pack 操作将默认使用 AssemblyName 或目录名称作为包的名称。

TitleTitle

明了易用的包标题,通常用在 UI 显示中,如 nuget.org 上和 Visual Studio 中包管理器上的那样。如果未指定,则改为使用包 ID。

AuthorsAuthors

其中名称以分号分隔的包作者列表,其中名称与 nuget.org 上的配置文件名称匹配。这些信息显示在 nuget.org 上的 NuGet 库中,并用于交叉引用同一作者的包。

PackageDescriptionPackageDescription

用于 UI 显示的包的详细说明。

DescriptionDescription

程序集的详细说明。如果未指定 PackageDescription,则此属性还可用作程序包的说明。

包的版权详细信息。

PackageRequireLicenseAcceptancePackageRequireLicenseAcceptance

一个布尔值,指定客户端是否必须提示使用者接受包许可证后才可安装包。默认值为 false

PackageLicenseExpressionPackageLicenseExpression

SPDX 许可证标识符或表达式。例如 Apache-2.0

下面是 SPDX 许可证标识符的完整列表。NuGet.org 在使用许可证类型表达式时只接受 OSI 或 FSF 批准的许可证。

许可证表达式的准确语法如下面的 ABNF 所述。

  1. license-id = <short form license identifier from https://spdx.org/spdx-specification-21-web-version#h.luq9dgcle9mo>
  2. license-exception-id = <short form license exception identifier from https://spdx.org/spdx-specification-21-web-version#h.ruv3yl8g6czd>
  3. simple-expression = license-id / license-id”+”
  4. compound-expression = 1*1(simple-expression /
  5. simple-expression "WITH" license-exception-id /
  6. compound-expression "AND" compound-expression /
  7. compound-expression "OR" compound-expression ) /
  8. "(" compound-expression ")" )
  9. license-expression = 1*1(simple-expression / compound-expression / UNLICENSED)

备注

一次只能指定 PackageLicenseExpressionPackageLicenseFilePackageLicenseUrl 中的一个。

PackageLicenseFilePackageLicenseFile

如果使用的许可证没有分配 SPDX 标识符,或者它是自定义许可证,则它是包中许可证文件的路径(否则,优先选择 PackageLicenseExpression

替换 PackageLicenseUrl,不能与 PackageLicenseExpression 结合使用,并且需要 Visual Studio 15.9.4、.NET SDK 2.1.502 或 2.2.101 或更高版本。

将需要通过显式地将许可证文件添加到项目中来确保许可证文件已打包,示例用法如下:

  1. <PropertyGroup>
  2. <PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
  3. </PropertyGroup>
  4. <ItemGroup>
  5. <None Include="licenses\LICENSE.txt" Pack="true" PackagePath="$(PackageLicenseFile)"/>
  6. </ItemGroup>

PackageLicenseUrlPackageLicenseUrl

适用于包的许可证的 URL。(自 Visual Studio 15.9.4、.NET SDK 2.1.502 和 2.2.101 起已弃用 )

PackageIconUrlPackageIconUrl

64x64 透明背景图像的 URL,用作 UI 显示中包的图标。

PackageReleaseNotesPackageReleaseNotes

包的发行说明。

PackageTagsPackageTags

标记的分号分隔列表,这些标记用于指定包。

PackageOutputPathPackageOutputPath

确定用于已打包的包的输出路径。默认值为 $(OutputPath)

IncludeSymbolsIncludeSymbols

此布尔值指示在打包项目时,包是否应创建一个附加的符号包。符号包的格式由 SymbolPackageFormat 属性控制。

SymbolPackageFormatSymbolPackageFormat

指定符号包的格式。如果为“symbols.nupkg”,将使用包含 PDB、DLL 和其他输出文件的 .symbols.nupkg 扩展创建旧符号包。如果为“snupkg”,将创建包含可移植 PDB 的 snupkg 符号包。默认值为“symbols.nupkg”。

IncludeSourceIncludeSource

此布尔值指示包进程是否应创建源包。源包中包含库的源代码以及 PDB 文件。源文件置于生成的包文件中的 src/ProjectName 目录下。

IsToolIsTool

指定是否将所有输出文件复制到 tools 文件夹,而不是 lib 文件夹。请注意,这不同于 DotNetCliTool,后者通过在 .csproj 文件中设置 PackageType 进行指定。

RepositoryUrlRepositoryUrl

指定存储库的 URL,该存储库是包的源代码所驻留和/或生成的位置。

RepositoryTypeRepositoryType

指定存储库的类型。默认值为“git”。

NoPackageAnalysisNoPackageAnalysis

指定 pack 不应在生成包后运行包分析。

MinClientVersionMinClientVersion

指定可安装此包的最低 NuGet 客户端版本,并由 nuget.exe 和 Visual Studio 程序包管理器强制实施。

IncludeBuildOutputIncludeBuildOutput

此布尔值指定是否应将生成输出程序集打包到 .nupkg 文件中。

IncludeContentInPackIncludeContentInPack

此布尔值指定是否将含有 Content 类型的任何项自动包含在生成的包中。默认值为 true

BuildOutputTargetFolderBuildOutputTargetFolder

指定放置输出程序集的文件夹。输出程序集(和其他输出文件)会复制到各自的框架文件夹中。

ContentTargetFoldersContentTargetFolders

此属性指定放置所有内容文件的默认位置(如果未为其指定 PackagePath)。默认值为“content;contentFiles”。

NuspecFileNuspecFile

用于打包的 .nuspec 文件的相对或绝对路径。

备注

如果指定了 .nuspec 文件,则以独占方式将其用于打包信息,并且不使用项目中的任何信息。

NuspecBasePathNuspecBasePath

.nuspec 文件的基路径。

NuspecPropertiesNuspecProperties

键=值对的分号分隔列表。

AssemblyInfoPropertiesAssemblyInfo properties

现在,AssemblyInfo 文件中通常存在的程序集特性将自动从属性生成。

PropertiesPerAttributeProperties per attribute

每个特性都有一个可控制其内容的属性,还有一个可以禁用其生成的属性,如下表所示:

特性属性要禁用的属性
AssemblyCompanyAttributeCompanyGenerateAssemblyCompanyAttribute
AssemblyConfigurationAttributeConfigurationGenerateAssemblyConfigurationAttribute
AssemblyCopyrightAttributeCopyrightGenerateAssemblyCopyrightAttribute
AssemblyDescriptionAttributeDescriptionGenerateAssemblyDescriptionAttribute
AssemblyFileVersionAttributeFileVersionGenerateAssemblyFileVersionAttribute
AssemblyInformationalVersionAttributeInformationalVersionGenerateAssemblyInformationalVersionAttribute
AssemblyProductAttributeProductGenerateAssemblyProductAttribute
AssemblyTitleAttributeAssemblyTitleGenerateAssemblyTitleAttribute
AssemblyVersionAttributeAssemblyVersionGenerateAssemblyVersionAttribute
NeutralResourcesLanguageAttributeNeutralLanguageGenerateNeutralResourcesLanguageAttribute

注意:

  • AssemblyVersionFileVersion 默认采用 $(Version) 的值而不带后缀。例如,如果 $(Version)1.2.3-beta.4,则值将为 1.2.3
  • InformationalVersion 默认是 $(Version) 的值。
  • 如果存在此属性,则 InformationalVersion 附加 $(SourceRevisionId)。可以使用 IncludeSourceRevisionInInformationalVersion 来禁用它。
  • CopyrightDescription 属性也可用于 NuGet 元数据。
  • Configuration 与所有生成过程共享,并通过 dotnet 命令的 —configuration 参数进行设置。

GenerateAssemblyInfoGenerateAssemblyInfo

一个布尔值,用于启用或禁用所有 AssemblyInfo 生成。默认值为 true

GeneratedAssemblyInfoFileGeneratedAssemblyInfoFile

生成的程序集信息文件的路径。默认为 $(IntermediateOutputPath) (obj) 目录中的某个文件。