Search code examples
c#asp.net.netasp.net-mvc-5iis-7.5

ASP.NET Web.config <runtime> element not inherited into child application


I have an ASP.NET MVC5 application created as an IIS website with its own .NET 4.0 CLR app pool and physical path at:

C:\Websites\XXX\Web\en-HK

Under this site I have a child application "zh" in IIS (another MVC5 application), again with its own .NET 4.0 CLR app pool and physical path at:

C:\Websites\XXX\Web\zh-Hans-HK

Both sites have their own web.configs, with the child one only overriding a single <appSetting> which is working. What is not working however is that the element in the parent does no appear to be inherited down. The element looks like:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
      <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>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

When I first run the child application in a browser I see a YSOD complaining about that MVC 3.0 can't be found - this is because a 3rd party DLL is looking for MVC 3 but the binding that should redirect to 5.2 isn't there.

If I paste the <runtime> element into the child web.config - the error goes away.

Is the <runtime> element prevented from being inherited in child application by design or is my set-up off? It doesn't appear to be protected in machine.config.

UPDATE

I think the issue is to do with assembly probing.

When I've enabled the assembly load trace I can see that the YSOD in the child app is caused by ELMAH's dependency on MVC3, when .NET probes the application config (my child apps web.config) it cant find any <assemblyBinding> info so moves on to check the aspnet.config, not my parent sites web.config which does have the <assemblyBinding> info.

enter image description here

I guess this behaviour is by design?


Solution

  • The Asp.Net engine composes your Web.config files following IIS hierarchy into a final configuration source that the .Net runtime uses for requests within specific web locations

    However, the <runtime> section is a bit special because it is so low level. It is not used by managed code but by the unmanaged .Net runtime host to define its overall behavior (assembly binding is the most common but GC related stuff and others)