TL;DR:您仍然可以从 .NET Core 3 甚至 .NET 5 引用(依赖于的包).NET Framework 程序集,但是您将收到一个运行时如果您调用任何依赖于 .NET Core 不(尚)支持的 API 或库的代码,则会出现 em> 错误。您可以使用 Microsoft 的 .NET Portability Analyzer 发现这些
背景
首先,ASP.NET Core 3.x applications can no longer target the .NET Framework 和announced by Microsoft in 2018 是正确的。该功能以前为 allowed ASP.NET Core applications to call into .NET Framework libraries,因此为迁移到 .NET Core 的 Web 应用程序提供了中间解决方案。
注意: 由于 .NET Framework 仅在 Windows 机器上运行,因此编写以 .NET Framework 为目标的 ASP.NET Core Web 应用程序会隐式限制这些应用程序在 Windows 机器上运行窗户。
行为
不过,即使面向 .NET Core 或现在的 .NET 5,您仍然可以引用 .NET Framework 包和程序集,前提是您在 Windows 计算机上并安装了相应的 .NET Framework。其内部工作有点复杂,但不足之处在于 .NET Core 和 .NET 5 将评估 .NET Framework 组装就好像它们是.NET Standard assemblies。如果 API 调用也在 .NET Core 运行时中实现,它将正常工作 — 但如果 API 调用仅是 .NET Framework 的一部分,您将收到一个例外。
惊喜!强调这是一个运行时异常非常重要。您仍然可以引用 .NET Framework 程序集、编写对有问题的成员的调用以及编译您的代码没有任何警告。但只要调用依赖于 .NET Framework 特定程序集的代码,就会收到运行时异常。
示例
在 .NET 3.0 中,大部分 .NET Framework 库已移植到 .NET Core。事实上,这包括您作为示例引用的大部分System.Drawing 库——尽管有good reasons you may not want to use them。但是,如果您再深入一点,就会发现很多库仍然不受支持。一个明显的例子是WebConfigurationManager,它可以用来访问web.config文件中的配置设置。
.NET 框架代码
因此,例如,假设您在 .NET Framework 类库中有以下函数,该函数从您的 web.config 的 <AppSetting>s 元素返回一个键数组:
public static class Configuration
{
public static string[] GetAppSettings() => System.Web.Configuration.WebConfigurationManager.AppSettings.AllKeys;
}
ASP.NET 核心代码
然后,在 ASP.NET Core 控制器中,您公开一个端点以检索此数据:
public class MyController: Controller
{
public IActionResult ApplicationKeys() => Content(String.Join(", ", Configuration.GetAppSettings()));
}
异常
在以 .NET Framework 为目标的 ASP.NET Core 2.x 应用程序中,这可以正常工作。但是,在 ASP.NET Core 3.x 或 ASP.NET Core 5 应用程序中,当您调用 /My/ApplicationKeys/ 路由时会收到以下运行时错误:
System.TypeLoadException:'无法从程序集'System.Web,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a'加载类型'System.Web.Configuration.WebConfigurationManager'。'
避免意外
如果你和我一样,这会让你非常紧张。当您尝试调用依赖于不受支持的代码的库时,您更愿意收到设计时错误,或者至少是编译时警告。幸运的是,Microsoft 提供了一个.NET Portability Analyzer,即also available as a Visual Studio Extension,正是为了这个目的。
从 .NET 5 开始,SDK 中还内置了一个 compatibility analyzer,它将识别特定平台上 .NET 5 运行时不支持的调用。这要求目标库使用 [SupportedOSPlatform()] 属性显式注释其类型,因此您不会收到任何旧 .NET Framework 类型的警告。但这将有助于识别针对各种平台的库的类似类型的兼容性问题。
示例
如果您在上述示例代码上运行可移植性分析器,例如,它将 output an Excel spreadsheet 识别 T:System.Web.Configuration.WebConfigurationManager 是 不支持 在例如.NET Core,Version=v3.1 或 .NET Standard + Platform Extensions,Version=v2.0。
注意: Microsoft 曾经提供 API Analyzer 作为 NuGet package,承诺在 Visual Studio 中提供设计时分析。不幸的是,the code 已经两年没有更新了,the latest release is 0.2.12-alpha。在我的评估中,它不能有效地发现问题。
示例项目
我整理了一个sample project on GitHub,它演示了上述行为。它包括以下项目:
两个 ASP.NET Core 网站都包含两个端点,它们调用相同的 .NET Framework 4.8 类库。第一个是“Hello world”示例,它可以在两个项目上正常执行,因为它完全依赖于通用 API:
http://localhost:5000/Basic/Index
第二个将在 ASP.NET Core 3.1 项目上失败,因为它调用了旧版 WebConfigurationManager API:
http://localhost:5000/Basic/Configuration
免责声明:这是一个快速而肮脏的存储库,我在发布之前将其放在一起以验证我的理解。如果有兴趣,我会整理并记录下来。不过,就目前而言,它可能对那些需要实际操作的人有用。
致谢
@Chris Pratt 提供了an excellent answer 去年报道了类似的材料。值得一读。