3

I'm using VS2017 with an ASP.NET project that I've inherited from another developer. I have the publish functionality set up to publish to a folder. This has all been working great until now.

The previous developer used EntityFramework, though all of the references were broken when I got the project, so I had to piece together what version. I'm using 6.2.0 currently and everything works fine. He apparently was using the automatic migration functionality. I've continued using this, but have had a couple situations where I had to enable data loss. I really don't want to do this, so the suggested path is to enable migrations and add the actual migrations. I'm not new to OR Mappers, but I am new to EF, so migrations are pretty new to me. In fact, it's been an uphill battle just to get things to work the way the docs say they are supposed to (see this thread)

So, now I am to the point of having my initial migration data. It seemed like the next step is to get this released to our dev server and then to our production server. So, being that I've used the publish functionality many times before with this project, I figured it would just work. Well, that's not the case now due to the changes I did to get EF migrations working.

The publish goes until it does this:

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v / -p 
C:\Users\Dan\Documents\Source\Repos\web- 
app\WebApp\obj\Release\AspnetCompileMerge\Source -u 
C:\Users\Dan\Documents\Source\Repos\web- 
app\WebApp\obj\Release\AspnetCompileMerge\TempBuildDir 

/global.asax(1,0): Error ASPPARSE: Could not load file or assembly 
'Microsoft.Build.Framework, Version=4.0.0.0, Culture=neutral, 
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system 
cannot find the file specified.

ASPNETCOMPILER(0,0): Error ASPRUNTIME: Could not load file or assembly 
'Microsoft.Build.Framework, Version=4.0.0.0, Culture=neutral, 
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system 
cannot find the file specified.

The first thing that struck me as interesting is that in order to get migrations to work, I had to install Microsoft.Build.Framework 15 (specifically I installed 15.1.1012 using nuget and then tried updating that to the latest, which is now 15.8.166). Seemed like more than a coincidence that this is a different version of the same library that is in the errors.

I saw some mention of needing to edit devenv.exe.config to change relative paths to absolute (here), but this didn't help.

I verified in the GAC that 4.0.0.0 is there. Apparently so is 14.0.0.0. From what I understand, installed versions that are less than 15 should be in the GAC.

I made sure Microsoft.Build.Framework was added (via nuget) to both my web app project as well as the project that has the EF context and migrations. The version 15 of Microsoft.Build.Framework was listed in both projects as a reference and was automatically set to Copy Local.

I tried changing the version referenced in my web app to 4.0.0.0, which initially had Copy Local set to false. Didn't help. Changed the 4.0.0.0 reference to Copy Local. This time, I'm met with a single error of:

Could not load file or assembly 'Microsoft.Build.Framework, 
Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one 
of its dependencies. The located assembly's manifest definition does not 
match the assembly reference. (Exception from HRESULT: 0x80131040)

Now, my thought was since it looks like multiple versions are involved, maybe it should be taken care of with a binding redirect. I rarely have to deal with binding redirects, so I'm not much of an expert, but I did look at the web.config and it appears something (I'm assuming Nuget install of Microsoft.Build.Framework 15) had already entered the following:

  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
  </dependentAssembly>

So, considering that 4.0.0.0 is in the GAC and considering there's a redirect that I believe would redirect any 4.0.0.0 reference to 15.1.0.0, why would I get errors about not being able to find 4.0.0.0? Is there something I'm missing? I assume this must be related to something aspnet_compiler.exe is doing on a publish, since I can build and test the app fine on my development machine.

Dan
  • 533
  • 8
  • 29
  • possible duplicate, https://stackoverflow.com/questions/43330915/could-not-load-file-or-assembly-microsoft-build-frameworkvs-2017 – Alex Terry Oct 05 '18 at 19:38
  • I believe I've tried everything in that thread except adding version 15 to the gac, which that answer suggests is more of a workaround than a solution. Though I may try that when I get back to my pc. The thread also seemed like those were steps to get the migration added. I'm already past that point. – Dan Oct 05 '18 at 20:03
  • Well, I guess adding version 15 to the gac was the solution. But there are MSFT employees saying "Please do not install Microsoft.Build.* in your GAC" Kind of makes me thing something else needs fixed though. – Dan Oct 06 '18 at 01:24
  • Having the same issue... runs on my Dev machines, but when I deploy, it fails. @Dan any news on what you did to fix this? – Eric Burdo Dec 06 '18 at 19:36
  • Only what I mentioned above, which is to install it into the GAC. And then after I did an upgrade to Visual Studio, it broke, which I think is why MS employees said not to do it. Had to uninstall from the GAC, then install again. That's on my dev machine which is the only place I've been building from. I have another person setting up CI/CD for the project, but he hasn't mentioned having this problem. – Dan Dec 07 '18 at 07:04

5 Answers5

1

In my case removing bindingRedirect from web.config and then installing latest nuget for Microsoft.Build.Framework worked like a charm.

Lucas Z
  • 11
  • 2
1

I had the exact same issue as described by OP.

Problem was solved by installing Microsoft Build Tools 2015

For me issue happened after moving from VS 2015 to VS 2017. However, I have heard few people reporting the same when a project created in VS 2015 is attempted to be published in VS 2017.

Sahil Shah
  • 95
  • 6
0

It's a Microsoft package issue, Microsoft seems to phase out support of older Nuget versions. This solution worked for me. Issue disappeared and now builds successfully.

In your Azure Build Pipeline > NuGet tool installer step, change Version of NuGet.exe to install to a newer version, like 5.4.0.

Check Nuget's latest ReleasedAndBlessed version at https://dist.nuget.org/tools.json.

Alfred Wallace
  • 1,741
  • 1
  • 14
  • 32
0

Like the OP, I have a reference to Microsoft.Build.Framework v15 and I found that simply ensuring there are no assembly redirects for the Microsoft.Build.Framework assembly in the web.config allows my deployments to work. Having a redirect breaks deployments because we do the ASPNETCOMPILE stage to ensure views syntax is correct and the build breaks there with the OP's error message.

Unfortunately, Visual Studio 20XX loves to silently re-add an assembly redirect for it to my web.config with every nuget operation, and I have to remove it every stinking time, usually after a failed build reminds me:

  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
  </dependentAssembly>
jpt
  • 162
  • 1
  • 11
  • I just found this documentation: https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file#bindingredirects-section which explains how to disable Nuget's sneaky adding of the binding redirect by adding a config file to your project. – jpt Feb 14 '22 at 22:32
0

My issue was uber specific but might help someone: I was using Reflection to do some operations dynamically, and for that I was loading assemblies like this:

    var types = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(p => (typeof(IMandatorId).IsAssignableFrom(p) || typeof(INullableMandatorId).IsAssignableFrom(p))
                && typeof(IEntityModel).IsAssignableFrom(p))
            .ToList();

However the GetTypes() method would fail for a specific assembly, which in my case was linked to a specific nuget package. I removed the package and stuff started working again. For those interested the package was:

Microsoft.VisualStudio.Web.CodeGeneration

and problems started appearing after I upgraded all packages to .net 6

Ricky
  • 258
  • 2
  • 11