Assembly binding redirect not working - asp.net-mvc

I am trying to deploy a test web app on Azure, but when I run the Azure emulator on my local machine I get this error from the Azure emulator console attached to my WebRole:
System.TypeLoadException: Unable to load the role entry point due to the following exceptions:
-- System.IO.FileLoadException: Could not load file or assembly 'System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
=== Pre-bind state information ===
LOG: User = COLLAB\mirko.lugano
LOG: DisplayName = System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
(Fully-specified)
LOG: Appbase = file:///C:/Code/Application/<MyWebProject>.Azure/csx/Debug/roles/<MyWebProject>/approot/bin
LOG: Initial PrivatePath = C:\Code\Application\<MyWebProject>.Azure\csx\Debug\roles\<MyWebProject>\approot\bin
Calling assembly : ActionMailer.Net.Mvc, Version=0.7.4.0, Culture=neutral, PublicKeyToken=e62db3114c02a1c2.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Code\Application\<MyWebProject>.Azure\csx\Debug\roles\<MyWebProject>\base\x64\WaIISHost.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: Attempting download of new URL file:///C:/Code/Application/<MyWebProject>.Azure/csx/Debug/roles/<MyWebProject>/approot/bin/System.Web.Mvc.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
---> System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.RuntimeModule.GetTypes()
at System.Reflection.Assembly.GetTypes()
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetRoleEntryPoint(Assembly entryPointAssembly)
--- End of inner exception stack trace ---
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetRoleEntryPoint(Assembly entryPointAssembly)
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CreateRoleEntryPoint(RoleType roleTypeEnum)
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(RoleType roleTypeEnum)
[fabric] Role state Unknown
Everything had been working fine as long as I had MVC3 installed on my local machine (the MVC3 assembly was in GAC), but since I removed MVC3 (Azure has no MVC installed), I am getting this error. My web app has MVC4 regularly included and that works fine. I had then thought about assembly binding redirection, and I noticed that in my web.config file I already have:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
...
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
...
</assemblyBinding>
</runtime>
which should be already correct, according to the documentation I have read around in internet. I have also tried setting the SpecificVersion property of my System.Web.Mvc.dll (version 4.0.0.0) to false but to no avail. Am I missing something? Shouldn't the calling assembly ActionMailer.Net.Mvc be automatically redirected to the correct version of the MVC assembly? Any ideas are greatly appreciated. Thanks.

In Azure WebRoles, by default (in Full IIS Mode) the RoleEntryPoint gets walled off from the rest of the WebRole, and runs in a different process.
A side effect of this is that your RoleEntryPoint will not have access to your web.config.
Azure SDK 1.3 -1.7 will look in WaIISHost.exe.config
Azure SDK 1.8+ will look in the WebRoleProjectName.dll.config.
With the newest change to the SDK, you should be able to place an app.config in your project and your role entry point should then have access to it.
You can read more about this in this Microsoft blog post or in this Stackoverflow post

Thank you Rune for the precious hint. That didn't solve my problem but it pointed me to the right direction, because I have the latest version of Azure SDK (1.8) and this WaIISHost.exe.config trick no longer works on the latest version of Azure. HERE is stated what I just said and the solution that worked for me, which is to rename the WaIISHost.exe.config file to MyWebAppName.dll.config (placing it at the same level of your web.config file in your web app and setting its Copy to output Directory property to 'Copy Always'. Of course this config file contains the binding redirect section as I described above.

As of today with the latest SDK a WebRoleProjectName.dll.config will be automatically generated for you with the contents of the Web.config and copied to the output directory.
However this won't be automatically be included in the deployment package! For this to happen you have to employ a kind of hackish solution: include the generated file in the project by selecting "show all files", then including just this file. The resulting change in the csproj should look like this (not, don't select it to be "Copy always"!):
<Content Include="bin\WebRoleProjectName.dll.config" />

Related

F#: Why does this code throws a System.IO.FileNotFoundException: 'Could not load file or assembly 'System.Runtime, Version=4.1.2.0, ...'

I created a F# Library (.NET Standard 2.0) and a WPF App (.NET Framework 4.7.2)
On the F# library, I have a file that I defined as a Resource:
This is using this code of the library:
let LeResourceFile(resourceName) =
let assembly = System.Reflection.Assembly.GetExecutingAssembly();
//var resourceName = "MyCompany.MyProduct.MyFile.txt";
use stream = assembly.GetManifestResourceStream(resourceName)
use reader = new System.IO.StreamReader(stream)
let result = reader.ReadToEnd();
result
let LogoBanco (CodigoDoBanco:string) =
match CodigoDoBanco with
| "001" -> LeResourceFile("BoletoBancarioFacil.templates.Logos.BB.png")
| _ -> ""
When I try to access the library function (.NET Standard 2.0) from the C# (NET 4.7.2) then I get this Exception:
System.IO.FileNotFoundException: 'Could not load file or assembly 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.'
Why does this happens and how to fix it, to make it work?
EDIT: I tried to find this System.Runtime on the NuGet on that F# library, but this specific version is not avaliable:
Here is the Stack Trace:
System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. O sistema não pode encontrar o arquivo especificado.
File name: 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at BoletoBancarioFacil.HTML.LogoBanco(String CodigoDoBanco)
at BoletoBancarioFacil.HTML.GeraBoletoHTML(Decimal amount, String LinhaDigitavel, String CodigoBarras) in C:\Users\tonyv\source\repos\siteApelosUrgentes\socio\cadastro\BoletoBancarioFacil\HTML.fs:line 49
at cadastro.MainWindow.GeraHTMLboleto(Titulo titulo) in C:\Users\tonyv\source\repos\siteApelosUrgentes\socio\cadastro\cadastro\MainWindow.xaml.cs:line 389
at cadastro.MainWindow.ExibeBoleto(Titulo titulo, Boolean Imprime) in C:\Users\tonyv\source\repos\siteApelosUrgentes\socio\cadastro\cadastro\MainWindow.xaml.cs:line 737
at cadastro.MainWindow.ListBoxTitulos_SelectionChanged(Object sender, SelectionChangedEventArgs e) in C:\Users\tonyv\source\repos\siteApelosUrgentes\socio\cadastro\cadastro\MainWindow.xaml.cs:line 987
=== Pre-bind state information ===
LOG: DisplayName = System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
(Fully-specified)
LOG: Appbase = file:///C:/Users/tonyv/source/repos/siteApelosUrgentes/socio/cadastro/cadastro/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : BoletoBancarioFacil, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\tonyv\source\repos\siteApelosUrgentes\socio\cadastro\cadastro\bin\Debug\cadastro.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Redirect found in application configuration file: 4.1.2.0 redirected to 4.1.2.0.
LOG: Post-policy reference: System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
LOG: Attempting download of new URL file:///C:/Users/tonyv/source/repos/siteApelosUrgentes/socio/cadastro/cadastro/bin/Debug/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Users/tonyv/source/repos/siteApelosUrgentes/socio/cadastro/cadastro/bin/Debug/System.Runtime/System.Runtime.DLL.
LOG: Attempting download of new URL file:///C:/Users/tonyv/source/repos/siteApelosUrgentes/socio/cadastro/cadastro/bin/Debug/System.Runtime.EXE.
LOG: Attempting download of new URL file:///C:/Users/tonyv/source/repos/siteApelosUrgentes/socio/cadastro/cadastro/bin/Debug/System.Runtime/System.Runtime.EXE.
This looks like one of your libraries isn't compatible with the dotnet runtime you are using. You can usually fix this with binding redirects. I would highly recommend using paket to manage your library dependencies. I would also take a look at the binding redirects feature. It can fix some of these version inconsistencies by creating runtime configs that remap the wrong versions at runtime onto the one you actually have. You can create these .config files manually as well but it's a pain. Here is an example redirect to keep all the dependent F# core versions mapped onto the one I actually have in a project
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<Paket>True</Paket>
<assemblyIdentity name="FSharp.Core"
publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535"
newVersion="4.5.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Cannot resolve dependency to assembly FSharp.Core 4.4.1.0 when using VS 2017

I have been developing in VS 2015 and F# 4.0 (4.4.0.0) for quite some time.
With the release of VS 2017, I want to open solutions in the newest VS for development work, but still for a while keep the projects as VS 2015, F# 4.0, .NET 4.5.2. The build server will also have to use VS 2015 for a while.
As far as I can remember, this kind of scenario has not been problematic in earlier VS version upgrades, but then I don't think I used F# at that time.
I opened the solution and tried to compile. I get this error in a C# application project. (There are other C# applications, and at least one references an F# library.)
Unknown build error, 'Cannot resolve dependency to assembly 'FSharp.Core, Version=4.4.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.
All my F# projects in the solution are 4.0 (4.4.0.0). I double checked.
Why is this happening?
I searched for "4.4.1.0", and discovered that the "obj" folder of the C# project had a .exe.config file that differed from the app.config. It had this extra information that is not in the app.config of the project.
<runtime>
...
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.4.1.0" newVersion="4.4.1.0" />
</dependentAssembly>
</assemblyBinding>
Why is this appended automatically, and why only in this particular C# project?
I tried to copy that section to the app.config of the project, and change it to 4.4.0.0 in both places, but that didn't work. Also tried to use "4.4.1.0" as upper limit of old version, and have "4.4.0.0" as new version, but still didn't work. Same compiler error.
Then I removed that section, and I referenced FSharp.Core 4.4.0.0 in the C# project. That finally got rid of the compile error.
The I ran the program. It crashed with this exception.
Unhandled exception: Could not load file or assembly 'FSharp.Core, Version=4.4.1.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)
I reinserted the section with the redirect, and now the program runs fine.
Just to sum up, I added a reference to FSharp.Core 4.0, and the redirect looks like this
<bindingRedirect oldVersion="0.0.0.0-4.4.1.0" newVersion="4.4.0.0" />
With these modifications, the solution still works as expected also in VS 2015.
I had the same problem, maybe this is helpful for someone:
In my case, the cause was that some of my C# projects with transitive dependencies on FSharp.Core were referencing the runtime's assembly installed on my system directly, instead of using the NuGet package. I.e. the reference didn't have a hint path pointing to the NuGet packages folder, and thus was picking the assembly from C:\Program Files\FSharp\... from the F# SDK. I solved this by removing the reference and reinstalling the FSharp.Core NuGet package.
So this:
<Reference Include="FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
Turns into:
<Reference Include="FSharp.Core, Version=4.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\FSharp.Core.4.5.2\lib\net45\FSharp.Core.dll</HintPath>
<Private>True</Private>
</Reference>
Check the assembly references of the assembly in the message. For me I had a reference to assembly X which had a reference to Y. Because Y was missing, I got this error. By referencing Y, the error was resolved for me.

Autofac 3.4 is missing, while 3.5 is called

Attempting to run the MVC 5.2 project, which is built successfuly, got the following error:
An exception of type 'System.IO.FileLoadException' occurred in
ProjectNamespace.WebUI.dll but was not handled in user code
Additional information: Could not load file or assembly 'Autofac,
Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da' or
one of its dependencies. The located assembly's manifest definition
does not match the assembly reference. (Exception from HRESULT:
0x80131040)
Assembly manager loaded from:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll Running under
executable C:\Program Files (x86)\IIS Express\iisexpress.exe
--- A detailed error log follows.
=== Pre-bind state information === LOG: DisplayName = Autofac, Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da
(Fully-specified) LOG: Appbase = file:///C:/ProjectPath/WebUI/ LOG:
Initial PrivatePath = C:\ProjectPath\WebUI\bin Calling assembly :
Autofac.Integration.Mvc, Version=3.3.0.0, Culture=neutral,
PublicKeyToken=17863af14b0044da.
=== LOG: This bind starts in default load context. LOG: No application configuration file found. LOG: Using host configuration file:
C:\Users\me\Documents\IISExpress\config\aspnet.config LOG: Using
machine configuration file from
C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Autofac, Version=3.4.0.0, Culture=neutral,
PublicKeyToken=17863af14b0044da LOG: Attempting download of new URL
file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/Temporary
ASP.NET Files/root/5c8bedab/6a36492/Autofac.DLL. LOG: Attempting
download of new URL
file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/Temporary
ASP.NET Files/root/5c8bedab/6a36492/Autofac/Autofac.DLL. LOG:
Attempting download of new URL
file:///C:/ProjectPath/WebUI/bin/Autofac.DLL. WRN: Comparing the
assembly name resulted in the mismatch: Minor Version ERR: Failed to
complete setup of assembly (hr = 0x80131040). Probing terminated.
My web.config has the following settings:
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
</dependentAssembly>
Spent hours trying to resolve it, but failed. Please help.
This problem has become quite common. It seems to come up when you have the Autofac, Autofac.Mvc5 and Microsoft.AspNet.Mvc>5.1.0 packages, even though Autofac.Mvc5 is stated to work with Microsoft.AspNet.Mvc(≥ 5.1.0 && < 6.0.0).
I suggest the classic solution of checking and adding the appropriate assembly binding redirects for autofac, not only in the project which references it but in projects referencing that project as well.
Another potential problem is having two entries for the
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
in your config, if you have your bindings in the second one move them to the first one. That fixed it for me in a situation where I was also encrypting some configuration settings and for some reason the binding redirects were not copied into the resulting config file.
I highly recommend the Assembly Binding Log Viewer, it helped me a lot in figuring out the issue, even though my final solution was a cowardly one, going to Autofac3.4.0.0 and Microsoft.AspNet.Mvc 5.1.0. I spent way too much time on fixing the problem.
Also, for those who are interested you can use the nuget manager to detect and fill in your assembly binding redirects: Get-Project -All | Add-BindingRedirect (from here). It might need some additions afterwards depending on your porjects and references but at least it's going to give you a clean slate to begin with.
Update
Microsoft.AspNet.Mvc 5.2.3 was released so I decided to try again. I updated every package involved in the "conflict" to the latest version (Autofac 3.5.2, Autofac.Mvc5 3.3.4, Microsoft.AspNet.Mvc 5.2.3). I updated the redirect bindings and it worked.

Could not load assembly WebPages.Deployment version 2 at host?

I have a ASP.NET MVC 2 website (VS2010) that I have upgraded to ASP.NET MVC 3 (VS2012) and this works fin on local IIS7 but when publishing it I get this exception on host :
Could not load file or assembly 'System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
After some seartch I found this that states that I should set CopyLocal on some of the references(inlcuding the System.Web.WebPages) and also use the publish tool in VS2012, but this generated the following exception?
Could not load file or assembly 'System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
And I can´t find any Deployment dll to set copyLocal?
How could I solve this?
Have a read of http://joel.net/getting-asp.net-mvc-3-working-on-discountasp.net
You need to add a reference to System.Web.WebPages.Deployment and set that also to CopyLocal.

Program crashes when using Managed DirectX with .Net Framework 4.0

We are having a problem using DirectSound with the Managed DirectX dlls and the .Net Framework 4.0
The program works fine with .Net Framework 2.0 - but we have a requirement to upgrade to 4.0 to use some other components.
When the program invokes the Sound module, it crashes with the exception noted below.
Anybody seen this one and know how to fix it?
==============================================
System.IO.FileNotFoundException was unhandled
Message=Could not load file or assembly 'Microsoft.DirectX, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
Source=Microsoft.DirectX.DirectSound
FileName=Microsoft.DirectX, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
FusionLog=""
[stack dump snipped]
InnerException: System.IO.FileNotFoundException
Message=Could not load file or assembly 'Microsoft.DirectX, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
FileName=Microsoft.DirectX, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
FusionLog==== Pre-bind state information ===
LOG: User = *****************
LOG: DisplayName = Microsoft.DirectX, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
(Fully-specified)
LOG: Appbase = file:///C:/Users/*********/Documents/Visual Studio 2010/Projects/************/bin/x86/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : Microsoft.DirectX.DirectSound, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\***********\Documents\Visual Studio 2010\Projects\****************\bin\x86\Debug\***************.exe.config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Redirect found in application configuration file: 1.0.2902.0 redirected to 2.0.0.0.
LOG: Post-policy reference: Microsoft.DirectX, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
InnerException:
I know this is a late reply but for me to get this working I had to find two DirectX DLL Microsoft.DirectX and Microsoft.DirectX.DirectInput and add then as a reference to the project.
Then just use the DirectX namespace for calling methods.
<!-- Uncomment this section when switching from Net2.0 to Net 4.0
It is intended to fix problems loading DirectX dlls - per Microsoft-->
<!--
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
-->
Officially the legacy DirectX Managed 1.1 assemblies do not support .NET 4.0. See this blog post for details.
You could look at using SlimDX or some other alternative...

Resources