C# asp.net Supporting multiple versions of a dll - c#

I have the following dll hell:
a ASP.Net project
references WebGrease
which references Antlr3.Runtime.dll 3.3.1.7705 [stored in /bin/ folder of the asp.net app]
references Custom project
which references NCalc.codeplex.com
which references Antlr3.Runtime.dll 3.1.3.22795 [stored in /bin/CustomProject/ folder of the asp.net app]
unsurprisingly these two version of Antlr are not working well together and I get "The located assembly's manifest definition does not match the assembly reference" errors
I am unwilling to modify the WebGrease project.
I am attempting to upgrade the NCalc project to use 3.3.1.7705 however I am struggling with this
Do you have any suggestions on how to get these two DLL's to work together?
EDIT unfortunately the NCalc code is not compatible with the newer version of antlr so I cannot used binding redirects
Thank you

Providing NCalc can use the later version of Antlr3.Runtime - ie there are no breaking changes you should be able to use a binding redirect to direct it to load the later version
eg in the web.config file ass something like
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NCalc" publicKeyToken="xxxxxxxxx" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.3.0" newVersion="3.3.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
I don't think the 4th digit on the versions is used

Related

DLL Couldn't Be Loading Because of Binding Redirect

I have a DLL project that uses the SendGrid Nuget package. The SendGrid package requires the Nuget package System.Net.Http 4.3.4. This DLL project I've then packaged into a Nuget package.
Now, I have a ASP.NET MVC project that includes my Nuget package. Because of dependency requirements installing it installs SendGrid, System.Net.Http, and other dependencies.
Now, when I have my web app try to send an email I got the following error.
System.IO.FileNotFoundException
HResult=0x80070002
Message=Could not load file or assembly 'System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Source=Bc3.Mail
StackTrace:
at Bc3.Mail.MailHelper.SendMessage(SendGridMessage message) in C:\Code\Shared Libraries\Bc3.Mail\Bc3.Mail\MailHelper.cs:line 166
at Bc3.Mail.MailHelper.SendMail(MailMessage mail) in C:\Code\Shared Libraries\Bc3.Mail\Bc3.Mail\MailHelper.cs:line 128
…
Now, I'm confused since I thought version 4.3.4 was installed. I checked the version of System.Net.Http in all my projects and it says it's version 4.2.0.0. Ok, I'm confused why it's showing 4.2 when I thought I installed 4.3.4. However, if 4.2 is referenced in my project how could it not find it?
Anyway, next I looked at my web.config file and saw this
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0"/>
</dependentAssembly>
I don't know anything about these binding redirect. But I decided to remove this and everything worked fine.
So my question is why?
Thanks
About binding redirects
Binding redirects allow the runtime to select alternative versions of a specific assembly. Binding redirects can be helpful because they reduce the strictness for binding to a specific version of an assembly. But, they can bring about conflicts.
https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/redirect-assembly-versions
Binding redirect after adding SendGrid
I noticed that adding a NUGET reference to SendGrid inserted the following binding redirects
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.2" newVersion="4.1.1.2" />
</dependentAssembly>
Creating a NUGET package that uses SendGrid
I created a simple class library project which references SendGrid and made a NUGET package. I placed this NUGET package in my private feeds folder and then referenced this NUGET package from another Framework project. The compiled .CONFIG file had the following binding redirect
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>
Possibility
My thoughts:
The binding redirect that you are seeing in the web.config might have been brought about by an inadvertent reference to some other NUGET package
Allow the compiler to generate binding redirects during the Build operation as opposed to manually adding binding redirects in the Web.config or app.config . The Project setting --> Application tab --> Auto-generate binding redirects should be checked.
Hope this helps.
It looks like something got messed up.
The binding redirect would have been put there when any 2 of your nuget packages wanted different versions of Net.Http.
Or you manually installed 4.2.
This would make all references to a Net.Http use the 4.2 one instead.
So that is what is happening, except it seems you don't have Net.Http 4.2 in your project anymore. It seems this redirect was accidentally left behind somehow (maybe git or something locked the file when it was trying to change it?)

Assembly.LoadFrom how behaves on multi version dll

I've a dll with 2.0.0.1 version in one server which can be downloaded by accessing http://someipaddress/assembly/test.dll and I'm having another application which need to download this test.dll and have to access those methods.
When surfing for this, i've got three different methods to do,
1. Assembly.LoadFrom()
2. Assembly.LoadFile()
3. Assembly.Load()
I've tried Assembly.LoadFrom("http://someipaddress/assembly/test.dll")
Now i've replaced test.dll with 2.0.0.2 version and
What will happen the application download 2.0.0.2 test.dll and already downloaded test.dll 2.0.0.1.
Application which dll will refer?
Will it use existing test.dll 2.0.0.1 since its already downloaded while accessing test.dll 2.0.0.2?
Please suggest on this.
It'll depend on how you're referencing the assembly. By default if there's no binding redirect, your new dll will cause an exception. You can get around this by specifying an binding redirect rule in your application's configuration file like so;
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Test" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.2" newVersion="2.0.0.2" />
</dependentAssembly>
</assemblyBinding>
</runtime>
But you'd need to update it upon getting the new version of the dll.

Assembly Binding redirect: How and Why?

This is not a problem question but a general understanding question on assembly binding redirect's working.
Queries
Why binding redirect shows only major version and not minor, build and revision numbers?
Does old and new version change only when there is change in major version?
<dependentAssembly>
<assemblyIdentity name="FooBar"
publicKeyToken="32ab4ba45e0a69a1"
culture="en-us" />
<bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
Why are binding redirects needed at all? Suppose you have application A that references library B, and also library C of version 1.1.2.5. Library B in turn also references library C, but of version 1.1.1.0. Now we have a conflict, because you cannot load different versions of the same assembly at runtime. To resolve this conflict you might use binding redirect, usually to the new version (but can be to the old too). You do that by adding the following to app.config file of application A, under configuration > runtime > assemblyBinding section (see here for an example of full config file):
<dependentAssembly>
<assemblyIdentity name="C"
publicKeyToken="32ab4ba45e0a69a1"
culture="en-us" />
<bindingRedirect oldVersion="1.1.1.0" newVersion="1.1.2.5" />
</dependentAssembly>
You can also specify a range of versions to map:
<bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.2.5" />
Now library B, which was compiled with reference to C of version 1.1.1.0 will use C of version 1.1.2.5 at runtime. Of course, you better ensure that library C is backwards compatible or this might lead to unexpected results.
You can redirect any versions of libraries, not just major ones.
We came across an issue with binding redirect for NewtonSoft.Json. We looked up the file version in win 10 file properties "9.0.1.19813", looked up the number and the redirect kept failing. Further investigation and found that we were looking at file version and not assembly version. So, I wonder if people are mistaking File Version (which changes often) and Assembly version (which you can't see in windows 10 File Explorer). To see the Assembly version of a dll you can run this in powershell. Replace the dll name with the one you want to find version for.
[Reflection.AssemblyName]::GetAssemblyName('C:\development\bin\Newtonsoft.Json.dll').Version
The result of above is.
Major Minor Build Revision
----- ----- ----- --------
9 0 0 0
See References:
How can i see the assembly version of a .NET assembly in Windows Vista and newer (WIndows 7, 2008)?
https://support.microsoft.com/en-nz/help/556041

Microsoft.data.edm.dll being copied from "somewhere" on build in VS 2013

I am collaborating with another developer using VS2013 and VSO.
The solution runs fine on his machine but mine complains of:
"Could not load file or assembly 'Microsoft.Data.Edm' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)"
We've isolated this to the fact that 1 project within the solution is copying version 6.5.0 of this DLL into the bin folder upon build which is overwriting the 6.5.2 version required by other parts of the solution.
We aren't sure where it is finding this version of the DLL as it only happens on my build. We are using various nuget packages but all are up to date and identical between our machines.
Does VS pick up DLLs such as this from "standard locations" on the machine somwehere? I searched my hard drive and found various versions of the DLL going from 2.0 to 2.6.2. The most suspect of these seems to be:
C:\Program Files\Microsoft ASP.NET\ASP.NET MVC 4\Packages\Microsoft.Data.Edm.5.2.0\lib\net40
Is there anywhere I can tell VS not to get this DLL from some random location?
Thanks
Try to build it with detailed MSBuild information (Tools -> Options -> Projects and Solutions -> Build and Run) and then copy the output and search for Microsoft.Data.Edm.dll to find where it's copied and where does it come from.
To force the copy of the correct version, you can add an assembly redirect to the app.config file of the project (you may already have this section if you have used NuGet):
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.6.2.0" newVersion="5.6.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
This will force the use of the correct version on compilation and will not try to get the other version from the GAC or the system PATH environment variable.

Error Using JSON.NET

I am trying to use JSON.NET and after including the .dll and trying to use one of the methods I get this error:
Could not load file or assembly 'Newtonsoft.Json.Net35, Version=4.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.
Any know why I might be this error?
Two things to check:
(1) You may have to "Unblock" the DLL. By default, when you download a .zip file from the Internet, that file, and all .dll or .exe files extracted from that .zip file, are given a file system attribute that prevents them from loading and executing. Right-click on the DLL in Windows Explorer, choose "Properties", and in the resulting dialog box click on the "Unblock" button. Or better yet, do that for the .zip file, and then re-extract all the files.
(2) The Newtonsoft JSON.NET library comes in five flavors: one each for .NET 2.0, 3.5, 4.0, Silverlight, and Windows Phone. You need to use the right one for your particular environment. I presume that this is a .NET 3.5 project?
In my case, I resolved this problem once I realized that a library that I was using was itself using the Json.NET but with the earlier version (3.5). Linking the second library to the new Json.NET version solved the issue.
Hope this helps.
You need to download release 1 instead of release 2 of the Newtonsoft.Json.
try to add assembly binding redirect to app config like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.5.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Related posts:
System.IO.FileNotFoundException
At least one module has an unresolved import
Debugging tests that require an external dll

Categories