NuGet包(.NET Standard 2.x)导致ASP.NET MVC5应用程序(.NET完整框架)崩溃

10

我有一个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()'

我猜测这里有一个.NET Standard版本的System.Web.Http,它没有这个方法,而我的应用程序选择解决这个问题而不是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服务)提取数据。当在RELEASE模式下编译这些程序集(其中我打开了代码分析等),我会收到以下错误报告:

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

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

另一个我看到的建议(并没有帮助我),是禁用项目创建序列化程序集。按照以下步骤执行此操作(可能有帮助,也可能没有,但值得一试):
1.在“解决方案资源管理器”中,右键单击出现错误的项目,然后转到“属性”。 2.在“生成”选项卡中,向下滚动到最底部,并将“生成序列化程序集”更改为“关闭”。
我尝试了这个方法,对我有用。然而,这两个项目都将对象序列化以发送到各种网络源,所以我最不想做的就是取消优化应用程序内的序列化...
您有什么建议或如何最好地继续进行?
更新14-May-2018: 我发现了Scot Hanselman的一篇关于NuGet包的好文章,其中提到:
正如Oren明智地说: “使用.NET Standard需要使用PackageReference来消除‘大量包’的痛苦,并正确处理传递依赖项。虽然您可以在没有PackageReference的情况下使用.NET Standard,但我不建议这样做。”
然而,有一个问题...在Visual Studio中,现在有一种简单的方法可以将程序集从旧的package.config迁移到PackageReference,详见此链接,但是该文章明确指出:
请注意,迁移工具目前不支持C++、JavaScript和ASP.NET(.NET Framework)项目。
当尝试进行此操作时,迁移工具会通知我,对于NuGet包Microsoft.AspNet.Mvc和Microsoft.AspNet.WebPages:
安装迁移后,“content”资产不可用。
更新23-May-2018:我发现其他几个人也遇到了类似的问题。来自GitHub:.NET 4.6.1/.NET Standard 2.0 build with SGen fails #1630。他们的“解决方案”再次是禁用序列化(见上文),这会破坏我的应用程序性能。

<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>

结论?
那么,我是否正确地得出结论,即要在.NET FullFramework应用程序中使用.NET Standard 2.x NuGet包,我需要使用PackageReference而不是package.config,而AspNet.MVC应用程序目前无法实现这一点?换句话说,目前还不可能。

1
我们已经完成了类似的旅程。我们手动编辑了 Web 项目的 .csproj 文件,通过删除 <ProjectTypeGuids> 元素,然后运行迁移工具,最后在 .csproj 文件中恢复该元素。就这样! 然而,团队中的大多数开发人员都发现使用 F5 在 IISExpress 中运行项目变得更慢了。我很感兴趣,您是否进一步探索并有相同的经验? - Andreas Folkesson
不得不放弃并放弃一个.NET Standard解决方案,回到.NET完整框架。令人沮丧...微软已经为此发布了一个问题:请参见[链接](https://github.com/dotnet/sdk/issues/1630) - DrGriff
1个回答

1
我遇到了一个问题,与 .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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接