Targeting a specific version of the .NET Framework

I find numerous opinions and understandings about side-by-side and in-place installations of the .NET Framework.  Here is my favorite explanation of this “.NET Versioning and Multi-Targeting – .NET 4.5 is an in-place upgrade to .NET 4.0”.  I also link to that same article in one of my IIS labs here, “Lab 5: Basic and Advanced Application Pool Settings”.  Check out these other articles I wrote as well about .NET Framework versions.

See this article as well “All about <httpRuntime targetFramework>”.

Here is my hypothesis: “if the .NET version you want to target exists in the following directory structure and you target it in your web.config file, your application will run using those binaries. ”  What I mean is, regardless of what you select from a drop down, whether in the Azure portal or in the IIS Management console, the targeted version in your web.config is the code base in which your code is compiled and executed.

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework

image

Figure 1, .NET Framework reference assemblies, how to target a specific version

On an Azure App Service, the same are found in this directory.

D:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework

image

Figure 2, .NET Framework reference assemblies, how to target a specific version

The way I will test my hypothesis is by creating an ASP.NET application that targets the .NET Framework 4.7.1, since this exists on both my client machine, Figure 1 and on the Azure App Service, Figure 2.  I will code something available only in >= 4.7, test it, then change the target to a version which does not support that feature.  Notice in Figure 3 that when creating my ASP.NET application I am targeting the .NET Framework version 4.7.1.

image

Figure 3, .NET Framework reference assemblies, how to target a specific version

I used pattern matching which is a new C# 7 feature available only in .NET version 4.7 or greater.  I wrote about that here “How to enable C# 7 in Visual Studio 2017” and I used the same method.  I passed the method a Circle class which fell through to the default: switch.

public class Circle
{
     public double Radius { get; }
     public Circle(double radius)
     {
         Radius = radius;
     }
}

I compiled it and it worked when I targeted 4.7.1, but the odd thing was that it worked even when I targeted 4.5.2.  So that blew my hypothesis out the window, for a moment.  You can see here (http://foursevenone.azurewebsites.net/) that I target 4.5.2 and the code which was supposed to only work in 4.7+ worked also.

Scratching my head and poking my brain, I quickly came to this conclusion.  In Figure 3, I targeted my ASP.NET application to .NET Framework 4.7.1 and by doing that Visual Studio, correctly, created my default application bundle and loaded all the 4.7.1 assemblies and dependencies into the \Bin folder.  So regardless of my targetFramework change to 4.5.2, the code still ran against the 4.7.1 version and worked.  I conclude that changing the targetFramework to a lower .NET Framework version doesn’t break the application.

When I then created another ASP.NET application that targeted 4.5.2, Figure 4, as expected I could not code and use the pattern matching feature.  And I even got a great error when I tried compiling it, Figure 5.

I also compared the assembly and compiler versions in the \Bin folder of each project and they were indeed different versions.

image

Figure 4, .NET Framework reference assemblies, how to target a specific version

image

Figure 5, .NET Framework reference assemblies, how to target a specific version

The hypothesis is true-ish because I targeted 4.7.1 in my first application and it ran.  In the second application I targeted 4.5.2 and it ran.  It depends on which version the application is compiled against and targeted when created in Visual Studio.  Even after pointing my 4.5.2 application to 4.7.1 I still could not run the pattern matching logic.

What I then did was to deploy my 4.5.2 ASP.NET application to here (https://fourfivetwo.azurewebsites.net/) and without the 4.7.1 code it ran perfectly.  However, I copied the pattern matching code from the 4.7.1 project into the code on the 4.5.2 web app and it crashed because the contents of my \Bin directory contain 4.5.2 assemblies and compilers, Figure 6.

image

Figure 6, .NET Framework reference assemblies, how to target a specific version

Simply setting the targetFramework to 4.7.1 in my web.config did not resolve the execution problem.  I would need to update the assemblies and dependencies in my application \Bin directory to make the code compile and work as expected.  However, this did prove, at least to me that you can target a specific version other than the most current or version shown in the drop-down on an Azure App Service or from the drop-down in the Application Pool settings in IIS.

In conclusion and summary, you can target whatever version of the .NET Framework you want so long as that version exists on the server where the application is deployed.