views:

301

answers:

1

I'm working on a new WCF web service that's to be hosted within an existing ASP.NET web application. When I attempt to run the .svc file for the service, I'm getting an exception that it can't find the file for an assembly.

Could not load file or assembly 'System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.

The trouble is, this service doesn't appear to reference this (particular) assembly anywhere. There is one referenced project that loads System.IdentityModel, but it references version 3.0.0.0. In fact, all of these projects target the 3.5 runtime and there are no references to any 4.0 assemblies anywhere.

Here is the <compilation> tag from the Web.config for the web application:

<compilation debug="true">
  <assemblies>
    <clear/>
    <add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.Management, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System.Configuration.Install, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System.Messaging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.EnterpriseServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
    <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
  </assemblies>
</compilation>

Note: The <clear /> tag was added later as a troubleshooting attempt. It did not appear to have any effect upon behavior. I added it because the ".NET Compilation" tab of the IIS configuration manager was giving me an error that System.Data was being added twice, though obviously not in this file. Adding <clear /> took care of it for me, but I couldn't find the offending duplicate it in the Machine.config and there is no base website Web.config, so I'm wondering if there might be somewhere I'm not looking that could be the cause of the problem.

The server is running Server 2008 with .NET 3.5 SP1. I get the same issue (though with System.Configuration instead of IdentityModel, but nonetheless...) on my local IIS installation, which is on Windows 7 x64 with .NET 4.0.

Does anyone know why it's attempting to load this assembly (when only version 3.0.0.0 is referenced) and what I can do to correct it?

+1  A: 

I figured out the issue and thought it might be helpful to others who might encounter the same problem.

When a WCF service is activated, part of the process uses Type.GetType(string) to obtain the type that represents the implementation of the service contract. Because Type.GetType(string) requires that the target type be either:

  • In the calling assembly (which, in this case, it would never be)
  • In mscorlib (again, which it would never be)
  • Fully specified with an assembly-qualified name

It will fail unless the type is specified using its assembly-qualified name.

Because of this (and to make specifying service types easier with just the namespace-qualified name), the activator will scan all referenced assemblies and call Assembly.GetType(string) (which can take just a namespace-qualified name) until it locates a compatible type.

While I can't explain where the 4.0 references were coming from specifically, it must have been in a referenced assembly. By altering the ServiceHost tag in the .svc file for my service to use the assembly-qualified name, WCF successfully loaded the service.

Adam Robinson