Answered by:
Assembly Version redirect doesn't work with a configSource in <runtime>

Question
-
Hi,
We have built a framework for our Company. It includes about 40 assemblies (about 7 services).
We have just delivered a new version (v1.2) of this framework. Each team using our framework must now decide to use or not this new version.
To facilitate the upgrade, we want to provide the settings to redirect the assembly version at the Application Level. Those settings will have to be added into the applications config files; we may not do it at the Machine Level and we can't force all the applications to use the new version of the framework (Application running in Prod must continue to run without any impact).
Because its a long list of settings, we want to put them in a separated config file and ask the teams to use it as an external source in their own web.config.Ex.: <runtime configSource="BindingRedirect.config" /> This does not work... It's really wierd because the result is 100% the same from a ConfigurationManager point of view.
We did a small test application (See here after). We run it once with the settings in the configSource and once with the settings directly in the application's config file. In both case, the <runtime> section contains the same settings. But when we use the configSource, the application does not load the new version of the framework.
Here is the code to test: IgnoreSection runtime = (IgnoreSection)ConfigurationManager.GetSection(@"runtime"); Debug.Print(SerializeSection<IgnoreSection>(runtime)); ConfigurationSection section = (ConfigurationSection)ConfigurationManager.GetSection(@"ourCustomSection"); Debug.Print(section.GetType().AssemblyQualifiedName);
public static string SerializeSection<TSection>(TSection mySection) where TSection : ConfigurationSection{
string sectionName = mySection.GetType().FullName; MethodInfo info = mySection.GetType().GetMethod("SerializeSection", BindingFlags.NonPublic | BindingFlags.Instance); return info.Invoke(mySection, new object[] { null, sectionName, ConfigurationSaveMode.Full }) as string;}
Here is the Debug output when using configSource:<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Framework" publicKeyToken="f510307097254a31" />
<bindingRedirect oldVersion="1.1.0.0" newVersion="1.2.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Framework.ourCustomConfigurationSection, Framework, Version=1.1.0.0, Culture=neutral, PublicKeyToken=f510307097254a31Here is the Debug output when NOT using configSource but settings the bindings directly in the application's config file.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Framework" publicKeyToken="f510307097254a31" />
<bindingRedirect oldVersion="1.1.0.0" newVersion="1.2.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Framework.ourCustomConfigurationSection, Framework, Version=1.2.0.0, Culture=neutral, PublicKeyToken=f510307097254a31
Any idea why it's not working ? Any workarround to avoid that each team must copy/paste this long list of settings in its own config file ? I my understanding, using a Policy file assembly (that has to be in the GAC) will redirect all the assembly versions for all the applications and is therefore not acceptable for us...
V.Wednesday, February 4, 2009 12:47 PM
Answers
-
As far as I can tell you, what you are seeing is 'By Design'. There are differnces between runtime parser and asp.net parsers, and the configSource is not processed by the runtime parser. The binder therefore doesnt really processes the config file you have specified via configSource.
Your understanding is right about the publisher policy, it will be a global change.
Another option (basides using a single config file), which you can consider is linkedConfiguration element, which is also a mechanism to supply configuration files, specifically to the loader.- Marked as answer by Valéry Letroye Friday, February 6, 2009 2:15 PM
Thursday, February 5, 2009 8:29 PM
All replies
-
As far as I can tell you, what you are seeing is 'By Design'. There are differnces between runtime parser and asp.net parsers, and the configSource is not processed by the runtime parser. The binder therefore doesnt really processes the config file you have specified via configSource.
Your understanding is right about the publisher policy, it will be a global change.
Another option (basides using a single config file), which you can consider is linkedConfiguration element, which is also a mechanism to supply configuration files, specifically to the loader.- Marked as answer by Valéry Letroye Friday, February 6, 2009 2:15 PM
Thursday, February 5, 2009 8:29 PM -
Thank you very very much !
This is exactly the trick I need. It works perfectly.
I didn't know about this element....
V.Friday, February 6, 2009 2:17 PM -
I thought it was working but I didn't do my test correctly. Actually, it does not work :(
Looking on internet for some help on this, I found that many people trying to use this element have the same issue as I do. But I didn't find any solution or any sample of working config files.
Could possibly someone confirm that I am using the right syntax:
Here is the full content of my external config file: BindingRedirect.xml
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Framework" publicKeyToken="f510307097254a31" />
<bindingRedirect oldVersion="1.1.0.0" newVersion="1.2.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Notice: I did also a try without the <runtime> and <assemblyBinding> tags...
Here is the full content of the app.config file at the application level:
<?
xml version="1.0" encoding="utf-8" ?>
<configuration>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<linkedConfiguration href="file://C:\BindingRedirect.xml"/>
</assemblyBinding>
</configuration>
I a try with and without a runtime section in the machine.config (When there was one, it was an empty one).
The following testing code is still returning a instance of the version 1.1.0.0 :
Assembly load;
load = Assembly.Load("Framework, Version=1.1.0.0, Culture=neutral,
PublicKeyToken=f510307097254a31");
Debug.Print(load.FullName); > Framework, Version=1.1.0.0, Culture=neutral, PublicKeyToken=f510307097254a31 I have double checked and both the version 1.1.0.0 and 1.2.0.0 are in the GAC
The doc is not clear. It says that "All linked configuration files are merged to form one file, similar to the behavior of the #include directive in C/C++."
But based on the sample there it's clear that "the assemblyBinding element is one level under <configuration>, instead of under <configuration><runtime>, where the normal binding policy resides." (Also read http://blogs.msdn.com/junfeng/archive/2005/02/08/369662.aspx)
I realy don't understand how the linked configuration files can be merged and produce the right xml... I.e. results in:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Framework" publicKeyToken="f510307097254a31" />
<bindingRedirect oldVersion="1.1.0.0" newVersion="1.2.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>V.
Monday, February 9, 2009 1:15 PM -
Use fuslogvw.exe to see how the loader resolved the assembly reference.
Hans Passant.Monday, February 9, 2009 1:44 PM -
Thanks to your advice (It's the first time I use this tool) I found that my linked file is well loaded. I can indeed see the following message in the log of Microsoft.VisualStudio.HostingProcess.Utilities: LOG: Processing linked configuration: file:///c:/temp/BindingRedirect.xml
If I put the assemblyBinding directly in the runtime section of the app.config, the fuslog contains the following entry:
> LOG: Redirect found in application configuration file: 1.1.0.0 redirected to 1.2.0.0.
I don't see any such message if I replace the runtime section by :
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<linkedConfiguration href="file://c:\temp\BindingRedirect.xml"/>
</assemblyBinding>
So, I am lost. Why are the binding redirects not applied concretly ? Does it means that the xml structure of my linked file is not correct ? I am still unsure about this one. I see only errors (ERR: There was an error parsing XML (hr = 0xc00ce555)). If I remove the tree first tags from this file: <runtime>, <assemblyBinding>, <dependentAssembly>.
Also notice that I found this message: WRN: Application configuration file binding redirects disallowed.
But I see this message both when using the <runtime> section in the app.config or the linked config file...
So I don't know if it's relevant.
V.
IMPORTANT NOTICE: I did clean my test solution and got the following error: Syntax error in manifest or policy file "C:\Temp\RedirectBindingTest\RedirectBindingTest\bin\Debug\RedirectBindingTest.exe.Config" on line 3. The element assemblyBinding appears as a child of element configuration which is not supported by this version of Windows.
So, it seems that the right structure in the app.config is actually :
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<linkedConfiguration href="file://c:\temp\BindingRedirect.xml"/>
</assemblyBinding>
<runtime>
</configuration>
??? It's not what I read... but anyway, it does not fix my problem.Monday, February 9, 2009 2:56 PM -
Here is my test app: http://www.alisce.be/test/RedirectBindingTest.zip
No way to load the System.Web.Extensions 3.5.0.0 instead of the 1.0.61025.0 with the linked file. It works however if using the redirect in the <runtime> section in the app.config.
V.Monday, February 9, 2009 4:57 PM -
Can you try these two things:
1.) make sure your application does not contain SxS manifest. I think linked configuration doesnt work with apps containing windows SxS manifest.
2.) Both the config should have all the required elements. I think this is how your orig.config will look :
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<linkedConfiguration href="......redirect.config" />
</assemblyBinding>
</runtime>
</configuration>
and the cofig specified in linked configuration (redirect.config)
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="" publicKeyToken="" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>Monday, February 9, 2009 6:58 PM -
Thanks for answering !
Indeed, there was an issue with the manifest (I cleaned too much my test app :o ).
I redid therefore my test application from scratch and (after a good meal) finally figured out that I could have to keep the <configuration> tag in my linked file. Now, it finally works perfectly.
The App.config or Web.config must have this structure (the linkedConfiguration is outside the runtime section)
<?xml version="1.0"?>
<configuration>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<linkedConfiguration href="file://C:\Users\Visual Studio 2008\Projects\RedirectBindingWin\LinkedApp.xml"/>
</assemblyBinding>
<runtime>
</runtime>
</configuration>And the LinkedApp.xml file of this sample must be like:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a"/>
<bindingRedirect oldVersion="2.0.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I did the test both in a win- and a web- application. It works in both case (As one could expect).
I think one should add such a complete sample in the msdn. Without any example, the following sentence from the msdn lead me to the wrong conclusion on the "linked configuration" file structure: All linked configuration files are merged to form one file, similar to the behavior of the #include directive in C/C++.
Such an include is more similar, IMO, to a copy/paste than a xml-nodes merge, isn't ?.
V.- Proposed as answer by floydy Tuesday, February 4, 2014 12:42 PM
Monday, February 9, 2009 9:07 PM -
Thanks for answering !
Indeed, there was an issue with the manifest (I cleaned too much my test app :o ).
I redid therefore my test application from scratch and (after a good meal) finally figured out that I could have to keep the <configuration> tag in my linked file. Now, it finally works perfectly.
The App.config or Web.config must have this structure (the linkedConfiguration is outside the runtime section)
<?xml version="1.0"?>
<configuration>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<linkedConfiguration href="file://C:\Users\Visual Studio 2008\Projects\RedirectBindingWin\LinkedApp.xml"/>
</assemblyBinding>
<runtime>
</runtime>
</configuration>And the LinkedApp.xml file of this sample must be like:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a"/>
<bindingRedirect oldVersion="2.0.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I did the test both in a win- and a web- application. It works in both case (As one could expect).
I think one should add such a complete sample in the msdn. Without any example, the following sentence from the msdn lead me to the wrong conclusion on the "linked configuration" file structure: All linked configuration files are merged to form one file, similar to the behavior of the #include directive in C/C++.
Such an include is more similar, IMO, to a copy/paste than a xml-nodes merge, isn't ?.
V.Thanks so much for this sample. I was banging my head trying to figure out what was wrong with my linkedConfiguration setting/file but I had it inside the <runtime> section. When I removed that it works great.
Cheers.
Tuesday, February 4, 2014 12:42 PM -
When I use VS2010 Debug configuration with "Enable the Visual Studio hosting process", LinkedConfiguration works. But if I uncheck this option, it always reports an error "This application has failed to start because the application configuration is incorrect. Review the manifest file for possible errors. Reinstalling the application may fix this problem. For more details, please see the application event log.". If I switch the configuration to Release, it always fails. Then I tried VS2013 & 2015, I can never make it work. Could you help check your project configuration? Thanks!Wednesday, January 11, 2017 9:41 PM