Why assemblyBinding is ignored? - c#

I have an IIS Application defined under the "Default Web Site" for which I would like to use a common assembly defined in another directory than /bin. I added a section to the web.config of the IIS Application with the location of the common assembly. However, it appears that that the assemblyBinding is ignored. Why is it ignored?
<runtime>
<probing privatePath="C:\Program Files\MyProduct\Bin\" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyProduct.Security" publicKeyToken="XXXXXXXXXXXXXXXXX" culture="neutral" />
<codeBase version="1.0.0.0" href="file:///c:\program files\myproduct\bin\MyProduct.Security.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>

From MSDN:
If the assembly has a strong name, the codebase setting can be
anywhere on the local intranet or the Internet. If the assembly is a
private assembly, the codebase setting must be a path relative to the
application's directory.

Related

How to chage default directory of .dlls creating after built with runtime and probing?

I want to move all .dlls to "lib" folder after building my application. Default program creates them in directory:
bin\Debug\netcoreapp2.2
And this is directory where I want to place my .dlls:
bin\Debug\netcoreapp2.2\lib
I create script which moves my .dlls to this folder and put it in post-built event. It works correctly.
Next, I add runtime to my app.config file like I saw in many tutorials and articles on stackoverflow.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib"/>
</assemblyBinding>
</runtime>
But, after building and starting my program, console says:
The application to execute does not exist:
app\bin\Debug\netcoreapp2.2\myDLL.dll
I want to know what's wrong with my application? How can I change the directory in which program is looking for .dlls?
I guess what you need is the codebase element in the configuration.
From documentation, If the assembly has a strong name, the codebase setting can be anywhere on the local intranet or the Internet. If the assembly is a private assembly, the codebase setting must be a path relative to the application's directory.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="neutral" />
<codeBase version="2.0.0.0"
href="http://www.litwareinc.com/myAssembly.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Hope this helps.

Load assembly from a path without copying it to bin folder

I have a simple c# application and I would like to reference an assembly from C:\..\..myassembly.dll without copying the thing to bin folder.
I there a way to change how is assembly being referenced/loaded?
Edit: the assembly is not in gac
Actually it is possible during runtime by using <codeBase> tag in your configuration:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyAssembly2" culture="neutral" publicKeyToken="307041694a995978"/>
<codeBase version="1.0.1524.23149" href="FILE://C:/Myassemblies/MyAssembly2.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
You can refer to the MSDN to get more specific info. The downside of this solution is that you have to manually specify assembly version.
Multiple solutions to your problem.
To avoid copying library to output folder set Copy Local to false by selecting .dll property.
Option 1:
Include below section in your configuration file and let allow runtime to load from location you specified.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyAssembly" publicKeyToken="2d65620afb84f19d" />
<codeBase version="1.0.0.0" href="C:\..\..myassembly.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Option 2:
Well known option, use reflection to load your assembly.
Assembly.Load(#"C:\..\..myassembly.dll")
Hope this helps !

How to use GAC assembly with specific version in C# app

I have 2 GAC assemblies called AAA (version 1.0.0.0 and version 2.0.0.0). The application currently is using version 1 (reference added by Browse-for-assembly, path is hardcoded to this file), but I want to use version 2.
To do it smoothly, I added some code to app.config:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="AAA"
publicKeyToken="dd8b40231cb0196b"
culture="en-us" />
<!-- Assembly versions can be redirected in app,
publisher policy, or machine configuration files. -->
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
But application still is using version 1.0.0.0 of assembly, why?
culture="en-us" />
That's wrong, assemblies that contain code are always neutral. Only satellite assemblies have culture. Or in other words, your bindingRedirect doesn't match any of the assemblies that the app is asking for. So has no effect. Be sure to delete the assembly from the project's bin\Debug directory so you can diagnose mistakes like this. The Fuslogvw.exe utility is also very handy, log all binds.
Fix:
culture="neutral" />

Runtime loading of private assemblies in a subdirectory

I have been trying to load a private assembly which is located in a subdirectory under the application base directory. I have an assembly named Sparrow.dll which is located under plugins directory (which is under application base dir also). Whenever I call Assembly.Load("Sparrow") I get a System.IO.FileNotFoundException.
I used app.exe.config with tag and it worked with a strong named version of the same assembly with the line below;
Assembly assem = Assembly.Load("Sparrow");
However, it does not work when I changed the assembly in to a weak assembly.
The content of the config file is below;
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly name="Sparrow, Culture=neutral, PublicKeyToken=xxxxxx">
<codeBase version="1.0.1.1" href="plugins/Sparrow.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I read many things, but I am not sure whether using tag for locating weak assemblies is a good practice or not.
You can use the probing element for that purpose:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="plugins" />
</assemblyBinding>
</runtime>
</configuration>
That element means that the plugins subfolder will be searched for assemblies.
Note however, that only directories that are on a descendent path of the application directory can be specified in that way.
The configuration file in your question has a mistake. According to documentation, the XML configuration should look like:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Sparrow"
publicKeyToken="null"
culture="neutral" />
<codeBase version="1.0.1.1" href="plugins/Sparrow.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
However, I think that using the probing element would be a better choice in your case.

.Net Publisher Policy: Both Assemblies required to be in the GAC?

I have created a publisher policy assembly following the post How to: Create a Publisher Policy. The policy redirects assemblies from the version 1.0.0.0 to the version 2.0.0.0.
This does work for me as long as the old assembly (v1.0.0.0) is located on the server (in the GAC). Is it possible to remove the old assembly version from the server?
The configuration I used:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Assembly.Name"
publicKeyToken="d24d3f23b4455982"
culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0"
newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Shame on me. I did a mess with the assembly versions. So the answer is: Yes, it works without the legacy assembly.

Categories