116

One of our ASP.NET MVC 5 web applications has the following web.config settings:

<system.web>
  <compilation debug="true" targetFramework="4.6" />
  <httpRuntime targetFramework="4.5" />
  <!--... many other things -->
</system.web>

It is not clear why are two targetFramework settings, and it seems to be wrong to compile targeting 4.6 then trying to run under 4.5...

Obviously I am missing something, but what?

g.pickardou
  • 32,346
  • 36
  • 123
  • 268
  • 5
    Related blog post https://blogs.msdn.microsoft.com/webdev/2012/11/19/all-about-httpruntime-targetframework/ – nu everest May 11 '17 at 23:25

2 Answers2

76

The reason of targetFramework existence in web.config is to keep compatibility issues out between breaking changes for each version of .NET Framework. The difference between targetFramework on compilation and httpRuntime belongs to each development and deployment environment.

According to MSDN blog:

<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.)

This element determines the assembly version used during compilation to create dependencies and related assemblies from current project.

<httpRuntime targetFramework="4.5" /> means that current project designed to use .NET 4.5 runtime assemblies without recompiling existing project assemblies in deployment machine before loading it into memory.

Hence, we can conclude that version number defined on targetFramework in httpRuntime element designed to maintain compatibility between compiled project and available assemblies in runtime usage, depending on which version of runtime files being used in target machine.

Thus, in your case, this is not a wrong behavior, the project creator(s) simply want to keep runtime compatibility to lowest runtime version available in target machine with similar characteristics (i.e. version 4.5), even the project compiled with newer version of .NET assemblies. The difference between version 4.5 and 4.6 is relatively small, thus keeping runtime version down to 4.5 still acceptable on this context.

Related references:

tibx
  • 840
  • 13
  • 20
Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
  • 15
    Maybe it's me, I still do not understand how can something "...designed to use .NET 4.5..." when we used 4.6 when selected "...a version of the .NET Framework’s reference assemblies are used when performing compilation..." – g.pickardou Oct 24 '16 at 05:55
  • 4
    .NET 4.6 is a subset update of .NET 4.5, thus also based from .NET 4.5 assembly references with some minor differences (note that .NET has backward compatibility support since version 2.0). In fact, the project will compile using version 4.6 assembly references, but able to use version 4.5 runtime references on target machine when higher version ones are not available. – Tetsuya Yamamoto Oct 24 '16 at 06:10
  • 5
    You are referring "backward compatibility". However it means by definition: a thing which expects lower version, will function seamlessly in context of higher version. (because the higher version is backward compatible" Not the reverse. – g.pickardou Oct 24 '16 at 06:23
  • 7
    Found good article that can explain little more about it at msdn. https://blogs.msdn.microsoft.com/webdev/2012/11/19/all-about-httpruntime-targetframework/ – dev Jul 10 '18 at 14:30
  • 3
    This answer looks so wrong and the answerer has got it back to front; So if I use features in 4.6 and compile with it, when I deploy to the target server (4.5), the app should fail because said features do not exist in older version. – joedotnot Jan 09 '20 at 01:16
  • @TetsuyaYamamoto i have one quick question if you agree that `` basically gets translated to ` ` and in that case explicit setting in `web.config` `` would be considered ? – rahulaga-msft Mar 26 '20 at 13:00
14

As per my understanding <compilation debug="true" targetFramework="4.6" /> is being suppressed by <httpRuntime targetFramework="4.5" /> since httpRuntime gets translated to following

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

So above setting is probably due to some misunderstanding or a bug if done by VS directly which I don't believe is true.

To understand how this setting and all other related stuff means this blog titled All about <httpRuntime targetFramework> written by a Microsoft employee might help you. But the gist of it is;

The .NET Framework (including ASP.NET) strives to maintain near-100% compatibility when an existing framework is updated on a machine. We try to ensure as much as possible that if an application was developed and deployed against .NET Framework 4, it will just continue to work on 4.5. This normally means keeping quirky, buggy, or undesirable behaviors in the product between versions, as fixing them may negatively affect applications which were relying on those behaviors.

Mubashar
  • 12,300
  • 11
  • 66
  • 95
  • 6
    In the blog post it suggests that any settings that are explicitly set in the web.config will not get overridden by what is implied by the httpRuntime setting: "Even though would normally imply , the runtime will notice that you have already explicitly set controlRenderingCompatibilityVersion and will respect your setting." – code4pi Sep 04 '18 at 19:26
  • 3
    Just for information, if compilation is set while httpRuntime is not set, the machinekey and pages setting will not have 4.5 as default value, need to set them manually. This is quite important while trying to share cookie between legacy website with .net core website. – Jarvan Jan 22 '19 at 08:09
  • what is the interpretation if the targetFramework is missing for both Compilation and HttpRuntime? – Anirudh Goel Mar 18 '19 at 23:20
  • please confirm by google but I think these attributes are used to limit the scope of application and framework to a specific version however if not specified it would probably assume that there is no restriction and will try to run whatever the latest version installed. This might not be good idea though assuming you may have some apps running in old version e.g. 4.0 while you install another app which might be using the recent framework functionalities e.g. 4.7.2. – Mubashar Mar 18 '19 at 23:57
  • 1
    @Jarvan: if **httpRuntime** **targetFramework** is not set, default value is 4.0 – tibx Feb 26 '21 at 09:06
  • I assumed the _Target framework_ setting in project files would determine the framework used during compilation of assemblies and that the setting in de web.config under _compilation_ determines the version for compiling aspx, cshtml etc. However, I cannot find any documentation on this. – R. Schreurs Aug 25 '22 at 11:59