Search code examples
c#nugetassembly-binding-redirectassemblybindingpublickeytoken

Visual Studio is looking for an old Nuget Package with no publicKeyToken


I have a Nuget package in my project which was previously unsigned and did not have a strong name.

I've released a new version of the package which is now signed.

When I add the new version of my Nuget package to my solution, anywhere within the project that references an assembly from the Nuget package, causes the following build error:

Error CS0012 The type 'JsonWebToken' is defined in an assembly that is not referenced. You must add a reference to assembly 'TSC.Business.DataContracts, Version=2.10.6.0, Culture=neutral, PublicKeyToken=null'.

As you can see, the compiler is still expecting a version of the assembly which has no PublicKeyToken.

I need to try and identify why the compiler is still expecting the publicKeyToken for this package to be null.

Things I've tried - all with no luck:

  • Completely uninstalling the old Nuget package by removing the old version from the packages.json, the packages directory, the csproj file, the bin path and running a full clean.

  • Validating that the publicKeyToken of the new version is correct in the packages.json - it is

  • Clearing my temporary ASP.Net files

  • Heck, even installing VS2019 and checking if the problem exists in there - which it does

Does anybody know where else the compiler could be looking for this null publicKeyToken?


Solution

  • I made the mistake of answering the question asked in my other answer, but actually reading the error message, it's clear the problem being experienced is caused by something other than what you think it is. I decided to keep my other answer as I've seen too many times people trying to change the contents of a package version they already used for testing and not understand why they can't see their changes when they try to use the updated package. Anyway, strong name signed assemblies can only have references/dependencies on other strong name signed assemblies, which means that your project is still referencing some package that is not strong name signed (or possibly a project reference, I can't remember if this could happen with packages.config projects, it shouldn't with PackageReference). But as the error message says, your project is not currently referencing TSC.Business.DataContracts, Version=2.10.6.0, Culture=neutral, PublicKeyToken=null at all.

    One way to quickly figure out which assembly your project is using that is not strong name signed is to strong name sign the project. Although this would mean that all packages you use must be strong name signed, which won't work if you use any 3rd party packages that aren't strong name signed. Anyway, if you did this, you would get this error:

    MSB3188: Assembly '<assembly>' must be strong signed in order to be marked as a prerequisite.

    Instead the error you're seeing says "The type 'JsonWebToken' is defined in an assembly that is not referenced". This means that you're referencing an assembly (I assume from a package) that has a method or property that returns an object of type JsonWebToken, and in your code you have used var jwt =. This causes your project to have an assembly dependency (different to package dependency) on the assembly that defined that type, but the assembly that defines the type was not passed to the compiler using the /r argument. Unless you're running csc.exe yourself, this means your project isn't getting the reference though a project or package reference.

    The cause could either be from using a package that doesn't correctly declare its own nuget dependencies, or maybe it's possible that your project is using packages.config and has a project reference to a project that uses TSC.Business.DataContracts, Version=2.10.6.0, Culture=neutral, PublicKeyToken=null. If your project was using PackageReference, then all dependencies are transitive, meaning if you reference a project that uses packages, those packages would automtically be available to your project as well. I don't think the same is true for packages.config projects, but I'm not sure exactly if ResolveAssemblyReferences happens in the build before or after running csc.exe.

    Assuming it's a package problem, not a transitive project reference problem, this can happen when package authors use nuspec files to create their packages as it's error prone. This is why the NuGet team highly recommend using SDK style projects (they can target the .NET Framework, they are not limited to .NET Core and .NET Standard) and use dotnet pack without a nuspec to automatically pack everything. NuGet dependencies are automatically added, so that type of package authoring mistake simply cannot happen. If you pack your packages with a nuspec, consider switching to SDK style projects and stop using a nuspec, otherwise check carefully your packages to make sure they have the right dependencies (nuget.exe pack can automatically add NuGet dependencies for package and project references, but it's more error prone).

    Maybe I should stop my message here, but there is another, less likely possibility. I hope briefly explaining it doesn't confuse more than help. Since you said that you did increment the package version number when you started strong name signing, I hope this means you also incremented the assembly version number. If so, then you should know if version 2.10.6.0 is expected to be strong name signed or not. If it should be, then you also have a problem with building and packing TSC.Business.DataContracts, or whatever package your project is using that depends on TSC.Business.DataContracts, because clearly it's using an unsigned version of the dll. If version 2.10.6.0 is a pre-signing version, then your project is using a package that was compiled against this old version of TSC.Business.DataContracts, although that package incorrectly failed to declare a nuget dependency on whatever package provides TSC.Business.DataContracts.dll.