【问题标题】:NuGet package (.NET Standard 2.x) breaking ASP.NET MVC5 application (.NET full framework)NuGet 包(.NET Standard 2.x)打破 ASP.NET MVC5 应用程序(.NET 完整框架)
【发布时间】:2018-05-10 15:12:07
【问题描述】:

(更新 - 见下文)

我有一个 ASP.NET MVC5 应用程序(多个程序集),都针对 .NET Full Framework 4.7.1

我最近添加了一个使用 .NET Standard 2 构建的(私有)NuGet 包。来自Quickstart: Create and publish a package using 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 文件 (x86)\参考 程序集\Microsoft\Framework.NETFramework\v4.7.1\Facades\System.IO.Compression.ZipFile.dll。 {姓名 程序集的} {程序集的路径}\SGEN

我发现一位post有以下建议:

我看到的另一个建议(对我一点帮助都没有)是禁用 项目从创建序列化程序集。遵循这些 执行此操作的步骤(可能有帮助,也可能没有帮助,但值得一试):

  1. 在解决方案资源管理器中,右键单击出现错误的项目并转到“属性”。
  2. 在“构建”选项卡中,滚动到最底部并更改“生成” 序列化程序集关闭

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

对可能出现的问题有什么建议,或者我应该如何最好地继续?

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

正如奥伦明智地说:

"使用 .NET Standard 需要使用 PackageReference 来消除 “很多包”的痛苦以及正确处理传递 依赖关系。虽然您可以在没有的情况下使用 .NET Standard PackageReference,我不推荐它。”

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

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

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

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

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

关闭

结论?

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

【问题讨论】:

  • 我们也经历过类似的旅程。我们通过删除 元素手动编辑了 web 项目的 .csproj 文件,然后运行迁移工具,然后恢复 .csproj 文件中的元素。瞧!然而,团队中的大多数开发人员都经历过,在 IISExpress 中使用 F5 运行项目的速度变慢了。如果您进一步了解并经历过同样的事情,我会很感兴趣?
  • 不得不放弃并放弃 .NET Standard 解决方案,回到 .NET Full Framework。郁闷....微软对此有一个问题:请参阅[链接](github.com/dotnet/sdk/issues/1630

标签: c# asp.net-mvc nuget .net-standard


【解决方案1】:

.Net Framework 4.8 应用程序和System.Buffers 程序集格式不正确

MarkKharitonov advice 已解决该错误。使用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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 1970-01-01
    相关资源
    最近更新 更多