WaIISHost.exe.config vs. app.config for Azure Cloud Service role config

If you have worked with Windows Azure Cloud Services and needed to do an assembly binding, you most likely have run in to this problem, of not knowign exactly where to place it. This post helps you to not go over 10 SO answers that have gotten outdated.

In fustration over having to google and find the answer for this each time Windows Azure SDK updates, or atleast half time times, i have created this blog post. I will try to keep the answer updated at the top and explain some details down the page.

Solution

The cloud service package need to have config settings or assembly bindings in <projectname>.dll.config and it should be in the approot/bin folder next to the dll that contains the RoleEntryPoint. So if you experience any LoadFileExceptions or other execptions due to config files missing. Make sure to check the packaged file for having that config file. If not try to restart visual studio, make sure you have set copy always for your <projectname>.dll.config and otherwise you can go over the post below and maybe get some ideas on how you can debug things. 

Theres nothing important to read below, only step by step what I did to solve my problem.

Problem

The problem happens when you want to use the web.config/app.config/WaIISHost.exe.config to have assembly bindings or settings in your Windows Azure Cloud Service Web Role. First of, WaIISHost.exe.config is out of the equation. If you are on a later SDK then 1.8, you wont need that any more.

So my project have a black Asp.Net website (WebRole), a Cloud Service Package (WebRole.Package) with the WebRole added as a Role. This runs without problem. Then I have a 3th c# library I am adding to my webrole that has some references that conflicts and therefore needs an assembly binding.

<configuration>
    <runtime>
    <assemblyBinding       xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

And without it my webrole deployment fails with the following FileLoadException.

System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Owin, Version=2.0.2.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: 'Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' at Owin.WebApiAppBuilderExtensions.UseMessageHandler(IAppBuilder builder, HttpMessageHandlerOptions options) at Owin.WebApiAppBuilderExtensions.UseWebApi(IAppBuilder builder, HttpConfiguration configuration)

So going over stackoverflow to find out where to put the binding and if using google and remembering to set google to only show results for the last month, you still end up with alot of questions / answeres. Most of them are outdated and some just dont work.

When you read or hear people saying that you need to create <projectname>.dll.config, then it should not be needed as duing the build visual studio renames web.config or app.config to <projectname>.dll.config. You can verify this by looking in the bin folder of the webrole project and its there by default. That was also my case, but still my project failed.

I did a test where I hadded App.Config and <projectname>.dll.Config next to my Web.Config and put both to copy always. When building the Web.dll.config file in the bin folder had the content of web.config. Put when you package the cloud project, then <projectname>.dll.config was not copyed to the approot folder of the package. 

I then remote desktopped to the VM and found that all the .config files, either of them, was in the approot folder but none in the approot/bin folder. So manually i moved my <projectname>.dll.config to the bin folder and right after the webrole was running. So after knowing where exactly the file should be located and what name it should have, I could start throbleshooting visual studio to see why this file was not placed correctly.

I cleaned and rebuilded the website project. And indeed my webrole.dll.config was in the bin folder of the folder. Then trying to do a package (context menu of the cloud service project) and renaming the package to .zip and looking at its content and finds the approot folder with all the binaries. No WebRole.dll.config file there now. So thats why it fails.

I tried adding App.Config and <projectname>.dll.config with copy always, they all end up in the approot folder and not the bin folder. Even though <projectname>.dll is in the bin folder of the website projects. 

Last step was to restart visual studio and then I tried setting web.config to copy always. This file ended up in the bin folder of the packaged cloud service, so atleast something changed after the restart. Then when going over properties of <projectname>.dll.config the setting was set back to not copying. So after setting it to copy and inspecting the cloud package again, it was there.

So not being able to explain why this seems buggy and where the exactly things go wrong, i atleast now know how to faster check if my package has its .config files before uploading to azure.



comments powered by Disqus