在ASP.NET MVC中,web.config文件中的TargetFramework设置是什么意思?

117
我们的一个ASP.NET MVC 5 Web应用程序有以下web.config设置:
<system.web>
  <compilation debug="true" targetFramework="4.6" />
  <httpRuntime targetFramework="4.5" />
  <!--... many other things -->
</system.web>

为什么有两个targetFramework设置并不清楚,似乎在针对4.6版本进行编译后尝试在4.5版本下运行是错误的...

很明显我漏掉了什么,但是是什么呢?


5
有关博客文章:https://blogs.msdn.microsoft.com/webdev/2012/11/19/all-about-httpruntime-targetframework/本文介绍了如何在ASP.NET应用程序中使用“目标框架”选项来指定运行应用程序所需的.NET Framework版本。这个选项可以通过web.config文件或者在IIS上的应用程序池设置中进行配置。正确地配置目标框架可以确保应用程序能够以正确的方式运行,并且可以充分利用所需的.NET Framework功能。 - nu everest
2个回答

76
web.config 中存在 targetFramework 的原因是为了避免在每个 .NET Framework 版本中的破坏性更改之间出现兼容性问题。 compilationhttpRuntime 上的 targetFramework 之间的区别属于每个开发和部署环境不同。
根据 MSDN 博客
<compilation targetFramework="4.6" />

Selects which version of the .NET Framework’s reference assemblies are used when performing compilation. (Note: Visual Studio requires that this element be present in Web.config, even though we auto-infer it.)

这个元素决定了编译期间使用的程序集版本,以创建当前项目的依赖项和相关程序集。 <httpRuntime targetFramework="4.5" /> 意味着当前项目被设计为在不重新编译现有项目程序集的情况下,在部署机器中加载到内存中时使用 .NET 4.5 运行时程序集。
因此,我们可以得出结论,httpRuntime 元素中 targetFramework 定义的版本号旨在维护已编译项目与运行时可用程序集之间的兼容性,具体取决于目标机器中使用的运行时文件版本。
因此,在您的情况下,这并不是错误的行为,项目创建者只是希望保持运行时兼容性,以最低的运行时版本为目标机器提供相似特性(即版本4.5),即使该项目是使用更新版本的 .NET 程序集编译的。版本4.5和4.6之间的差异相对较小,因此在这种情况下仍然将运行时版本保持在4.5是可以接受的。
相关参考文献:

16
也许是我理解有误,我还不明白为什么当我们选择“……在编译时使用 .NET 4.5……”时,却使用了 4.6 版本的“…….NET Framework 的参考程序集版本……”。 - g.pickardou
4
.NET 4.6 是 .NET 4.5 的一个子集更新,因此也是基于 .NET 4.5 程序集引用,并带有一些小的差异(请注意,自版本 2.0 起,.NET 具有向后兼容性支持)。实际上,该项目将使用 4.6 版本的程序集引用进行编译,但当目标计算机上没有更高版本的引用时,能够使用 4.5 运行时引用。 - Tetsuya Yamamoto
5
您正在提到“向后兼容性”。然而,按照定义,它的意思是:一个期望较低版本的东西,在更高版本的环境中可以无缝运行(因为较高版本是向后兼容的),而不是反过来。 - g.pickardou
7
在 MSDN 上找到了一篇好文章,可以更详细地解释它:https://blogs.msdn.microsoft.com/webdev/2012/11/19/all-about-httpruntime-targetframework/。 - dev
3
这个答案看起来很错误,回答者完全颠倒了;所以,如果我在4.6中使用功能并进行编译,当我部署到目标服务器(4.5)时,应用程序应该会失败,因为旧版本中不存在这些功能。 - joedotnot
@TetsuyaYamamoto,我有一个快速问题,如果您同意<httpRuntime targetFramework="4.5" />基本上被翻译成<compilation targetFramework="4.5" /> <machineKey compatibilityMode="Framework45" /> <pages controlRenderingCompatibilityVersion="4.5" />,在这种情况下,在web.config中明确设置<compilation targetFramework="4.6" />是否会被考虑? - rahulaga-msft

14

据我理解,<compilation debug="true" targetFramework="4.6" /><httpRuntime targetFramework="4.5" /> 抑制了,因为 httpRuntime 会被翻译成以下内容

<compilation targetFramework="4.5" />
<machineKey compatibilityMode="Framework45" />
<pages controlRenderingCompatibilityVersion="4.5" />

如果是由VS直接完成的,那么上述设置可能是由于某种误解或错误引起的,我不认为这是真的。

要理解此设置及所有相关内容的含义,可以阅读微软员工撰写的题为“All about <httpRuntime targetFramework>”的博客。但其要点是:

.NET Framework(包括ASP.NET)在更新机器上的现有框架时,努力保持近乎100%的兼容性。我们尽可能确保,如果应用程序是针对.NET Framework 4开发和部署的,它将继续在4.5上正常运行。这通常意味着在版本之间保留古怪、有缺陷或不受欢迎的行为,因为修复它们可能会对依赖这些行为的应用程序产生负面影响。


6
在博客文章中,它建议任何在 web.config 中明确设置的设置都不会被 httpRuntime 设置所暗示的覆盖:“即使 <httpRuntime targetFramework="4.5" /> 通常会暗示 <pages controlRenderingCompatibilityVersion="4.5" />,但运行时将注意到您已经明确设置了 controlRenderingCompatibilityVersion 并将尊重您的设置。” - code4pi
3
仅供参考,如果在未设置httpRuntime的情况下启用编译,机器密钥和页面设置将不具有4.5的默认值,需要手动设置。在尝试在.NET Core网站与旧版网站之间共享cookie时,这非常重要。 - Jarvan
如果Compilation和HttpRuntime都缺少targetFramework,那么这意味着什么解释? - Anirudh Goel
请确认一下,但我认为这些属性用于限制应用程序和框架的范围到特定版本,但如果未指定,则可能会假定没有限制,并尝试运行安装的最新版本。虽然这可能不是一个好主意,因为您可能有一些正在运行旧版本(例如4.0)的应用程序,而您安装另一个可能使用最新框架功能(例如4.7.2)的应用程序。 - Mubashar
1
@Jarvan:如果未设置httpRuntime targetFramework,则默认值为4.0。 - tibx
我曾经认为项目文件中的“目标框架”设置将决定编译程序集时使用的框架,而在web.config文件中“编译”下的设置则决定了编译aspx、cshtml等文件的版本。然而,我找不到任何关于此的文档说明。 - R. Schreurs

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