Tuesday, April 15, 2014

SOLVING - Could not load file or assembly or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.

This is quite possibly one of the most frustrating errors you can get after upgrading a Nuget package in an Asp.Net MVC project. If this is the first time you are getting it, you are likely wondering what is and where is the assembly's manifest. Well fear not mighty soldier developers because I have the information that will help you get running in no time. First an explanation.

When you update an existing Nuget package, that update often has side effects. What does that mean? Well the packages you need often depend on other packages and when you run the Nuget update, the package you need might pull in updates to the packages IT needs even though you didn't specify that you wanted those other packages updated. That was a  mouthful! The dependencies being updated are side effects that you may or may not have planned for. On the surface, this seems like it might be OK. As long as the update happens to the files you need and things still build, you are fine. However, this isn't always the case. I'm going to run through what happens when an update happens.

For this example, I'm going to say we are updating Package A.
  1. Package A depends on Packages K, L and M.
  2. You already have a version of Packages K, L and M installed on your machine.
  3. Package A needs to upgrade Packages K, L and M BEFORE it can install itself.
  4. Package M is needed by Package R so it can't be uninstalled unless Package R is uninstalled.
  5. The update  uninstalls Package R, Package M, Package L and Package K and then installs the newer versions of each package it relies on and the version of Package R that works with Package M. 
  6. After the new versions of the dependencies have all been installed, Package A installs the latest version of itself.
  7. The package.config file is updated to include the version information for the newly installed files.
  8. The dependentAssembly area in the web.config file is updated to include dependency information and establish the backward capability of the newly updated files.

That is a lot! It is no wonder then that subtle side effects (aka hidden problems) can arise during that process. It is involved! If everything runs smoothly, all of the references are updated accordingly and all is right with the world. However, nothing ever runs smoothly does it?

Sometimes, due to all of the installing and uninstalling that takes place, the web.config file does NOT get updated by the Nuget Package you are running! This is where we run into errors like -

Could not load file or assembly 'Whatever.File' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Basically what this error SHOULD say is, "The web.config and package.config files do not match what is in the References folder"! There you have it - I have just rewritten a Microsoft error into something that a developer can actually understand? Did hell freeze over? Anyway, THAT is the problem. Sometimes when these packages uninstall and reinstall dependent packages, they do NOT update the packages.cofig and web.config accordingly. If the web.config references a version of the package that no longer exists, you  are going to get the "Could not load file or assembly...blah...blah....blah" error! So how do we solve this issue? The solution is easy.

  1. First, identify the file that the system is complaining about. It should be easy to do since the error message will list the file. For example, in the error below, Microsoft.Owin.Security.OAuth is the culprit. Could not load file or assembly 'Microsoft.Owin.Security.OAuth' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
  2. Second, go the References folder in your project and look for the file specified. When you find it, right click on it and select Properties (Alt-Enter) and look at the Version. Make a note of it. This is the actual version that is installed on your system.
  3. Third, go to the packages.config file and find the file. Check to see that the version number for the file listed in the packages.config matches the version you have specified in your References folder. 
  4. Fourth, check the web.config dependentassembly area for the file. The bindingDirect  areas has an oldVersion and newVersion area. The oldVersion area should end with a version number that is EQUAL to the version number you have installed and the newVersion number should MATCH what you have installed. For example, if you have version 5.0 of System.Web.Mvc, then your dependentAssembly and associated bindingRedirect should look like the following - 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
 

    </assemblyBinding>

 After you are done, clean and rebuild your project!
 Smile :-). Either your project built successfully and you can see your stuff or you have to repeat the steps above for another file until they have all been corrected.

Notice the highlighted areas. The newVersion is what is installed on your system. The oldVersion represents all of the versions the newVersion should be able to handle. If this web.config information is out of sync with the version information in your packages file and in your project, then you will get an error.

Please note - sometimes you have to manually change MORE than just one file to get things running. I have one project in which I had to update 5 references from different packages. Each situation will be different. If you get another file error, correct that one and keep going until you get a clean build and can run your project.

If you want, you can run the Nuget Package Manager and update the one package that is giving you an issue. However, sometimes that is not the best approach if that package  has dependent relationships. You can end up in what I call "Package DLL Hell" - where one package updates another package and each update keeps causing other side effects! Hey - wasn't this what we were supposed to be SAVED from using Nuget? LOL.....anywho....following the steps above will get you going!

Smooches,

Kila Morton







4 comments:

Priscila said...

This article help me very much! Thanks a lot!

MKB said...

I have traced all the suggested steps and everything is in order but the error won't go away. I am experiencing a problem with Raven.Client.Lightweight. Somehow my tests are running with version 1.2.0.0 whereas I have updated to version 2.0.3.0. Nothing else points to version 1.2.0.0 and I have trouble finding where it picks this information from.

Unknown said...

This is fantastic! I was banging my head against the wall because of newtonsoft.json versions and this fixed the problem. Thanks from a newb...

MarkTM said...

Thank you ever so much for this. I've spent most of the day uninstalling and reinstalling packages to fix the problem. Ironically all my versions were correct. But the last bit Clean and Build fixed it.