首页 > 解决方案 > NuGet 包(.NET Standard 2.x)打破 ASP.NET MVC5 应用程序(.NET 完整框架)

问题描述

(更新 - 见下文)

我有一个 ASP.NET MVC5 应用程序(多个程序集)都解决了 .NET Full Framework 4.7.1

我最近添加了一个使用 .NET Standard 2 构建的(私有)NuGet 包。从快速入门:使用 Visual Studio (.NET Framework) 创建和发布包

除非您有其他选择的理由,否则 .NET Standard 是 NuGet 包的首选目标,因为它提供与最广泛的消费项目的兼容性。

从那以后,事情就不一样了......我在下面提到了一系列错误,但我怀疑它们都是同一个问题的症状(最后讨论)。

请注意:我使用的是 Visual Studio 15.7.1,所有 NuGet 包都使用 package.config 管理格式而不是 PackageReference。

第一个问题

找不到方法:'System.Collections.ObjectModel.Collection`1 System.Web.Http.HttpConfiguration.get_MessageHandlers()'

我的猜测是 System.Web.Http 的 .NET Standard 版本没有此方法,而我的应用程序选择解决此问题而不是 4.7.1 框架。

我通过将以下内容添加到我的 web.config 文件来部分解决此问题:

<dependentAssembly>
    <assemblyIdentity name="System.Net.Http" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>

我说“部分”修复了它,这解决了在我的 DEV 环境(使用 Visual Studio)中运行时的问题,但是当发布到我们的 QA 环境时,问题仍然存在。有想法该怎么解决这个吗?

注意:MVC 项目对 System.Net.Http 的引用存在于以下路径中(它不是 NuGet 包):

C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net471\lib\System.Net.Http.dll

第二个问题 其中两个程序集涉及从各种 Web 源(WCF、web-api、web-service)中提取数据。在 RELEASE 模式下编译这些(我打开了代码分析等)时,我收到以下错误报告:

尝试加载格式不正确的程序集:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.7.1\Facades\System.IO.Compression.ZipFile.dll。{程序集的名称} {程序集的路径}\SGEN

我发现一篇帖子有以下建议:

我看到的另一个建议(根本没有帮助我)是禁止项目创建序列化程序集。请按照以下步骤执行此操作(它可能有帮助也可能没有帮助,但值得一试):

  1. 在解决方案资源管理器中,右键单击有错误的项目并转到属性。
  2. 在 Build 选项卡中,滚动到最底部并将 Generate Serialization Assembly 更改为 Off

我试过了,是的,它对我有用。然而,这两个项目正在序列化对象以发送到这些不同的 Web 源,所以我想做的最后一件事是在我的应用程序中取消优化序列化......

关于可能出了什么问题,或者我应该如何最好地进行的任何建议?

2018 年 5 月 14 日更新 我发现了来自Scot Hanselman的一篇关于 NuGet 包的精彩文章,其中指出:

正如奥伦明智地说:

“使用 .NET Standard 要求您使用 PackageReference 来消除“大量包”的痛苦,并正确处理传递依赖项。虽然您可以在没有 PackageReference 的情况下使用 .NET Standard,但我不推荐它。”

但是,有一个问题....在 Visual Studio 中,现在有一种简单的方法可以将程序集从旧的 package.config 迁移到 PackageReference,详见此链接,但该文章明确指出:

请注意,迁移器目前不支持 C++、JavaScript 和 ASP.NET (.NET Framework) 项目。

在尝试此操作时,迁移工具适时通知我,对于 NuGet 包 Microsoft.AspNet.Mvc 和 Microsoft.AspNet.WebPages:

迁移后安装软件包时,“内容”资产不可用

2018 年 5 月 23 日更新我发现其他几个人也遇到了类似的问题。来自 GitHub:使用 SGen 构建的 .NET 4.6.1/.NET Standard 2.0 失败 #1630。他们的“解决方案”再次禁用序列化(见上文),这会破坏我的应用程序的性能。

<GenerateSerializationAssemblies>关闭</GenerateSerializationAssemblies>

结论?

那么,我是否可以得出这样的结论:要在 .NET FullFramework 应用程序中使用 .NET Standard 2.x NuGet 包,我需要使用 PackageReference 而不是 package.config,而这目前在 AspNet.MVC 应用程序中是不可能的?换句话说,目前是不可能的。

标签: c#asp.net-mvcnuget.net-standard

解决方案


我遇到了 .Net Framework 4.8 应用程序和System.Buffers程序集格式不正确的问题

MarkKharitonov 的建议已经解决了这个错误。有了Directory.Build.targets文件,我可以毫无问题地构建一个项目。

<Project>
  <ItemGroup>
    <ReflectionOnlyAssemblyNames Include="Microsoft.Bcl.AsyncInterfaces"/>
    <ReflectionOnlyAssemblyNames Include="System.Buffers"/>
    <ReflectionOnlyAssemblyNames Include="System.Numerics.Vectors"/>
    <ReflectionOnlyAssemblyNames Include="System.Runtime.CompilerServices.Unsafe"/>
  </ItemGroup>
  <Target Name="RemoveDesignTimeFacadesBeforeSGen" BeforeTargets="GenerateSerializationAssemblies">
    <ItemGroup>
      <_ReflectionOnlyAssembly_Names Include="@(_ReferencePath_Names)"
                                     Condition="'@(ReflectionOnlyAssemblyNames)' == '@(_ReferencePath_Names)' And '%(Identity)' != ''"/>
    </ItemGroup>
    <ItemGroup>
      <ReferencePath Remove="@(_DesignTimeFacadeAssemblies_Names->'%(OriginalIdentity)')" />
      <ReferencePath Remove="@(_ReflectionOnlyAssembly_Names->'%(OriginalIdentity)')" />
    </ItemGroup>
    <Message Importance="normal" Text="Removing DesignTimeFacades from ReferencePath before running SGen." />
  </Target>
  <Target Name="ReAddDesignTimeFacadesBeforeSGen" AfterTargets="GenerateSerializationAssemblies">
    <ItemGroup>
      <ReferencePath Include="@(_DesignTimeFacadeAssemblies_Names->'%(OriginalIdentity)')" />
      <ReferencePath Include="@(_ReflectionOnlyAssembly_Names->'%(OriginalIdentity)')" />
    </ItemGroup>
    <Message Importance="normal" Text="Adding back DesignTimeFacades from ReferencePath now that SGen has run." />
  </Target>
</Project>

推荐阅读