1

Closed

Reflection exception when probing for WebAPI controllers

description

I am trying to add webAPI to my existing .Net 4 RC app. When I try to access the webAPI route I get errors like:

<Exception xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/System.Web.Http.Dispatcher">System.IO.FileNotFoundExceptionCould not load file or assembly 'DevExpress.XtraEditors.v11.1, Version=11.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a' or one of its dependencies. The system cannot find the file specified.</Message><StackTrace>
Server stack trace:
at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes)
at System.Reflection.RuntimeAssembly.GetExportedTypes()
at System.Web.Http.Dispatcher.DefaultHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver)
at System.Web.Http.WebHost.WebHostHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver)
at System.Web.Http.Dispatcher.HttpControllerTypeCache.InitializeCache()
at System.Lazy1.CreateValue()

Exception rethrown at [0]:
at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes)
at System.Reflection.RuntimeAssembly.GetExportedTypes()
at System.Web.Http.Dispatcher.DefaultHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver)
at System.Web.Http.WebHost.WebHostHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver)
at System.Web.Http.Dispatcher.HttpControllerTypeCache.InitializeCache()
at System.Lazy
1.CreateValue()
at System.Lazy1.LazyInitValue()
at System.Lazy
1.get_Value()
at System.Web.Http.Dispatcher.DefaultHttpControllerSelector.InitializeControllerInfoCache()
at System.Lazy1.CreateValue()

Exception rethrown at [1]:
at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes)
at System.Reflection.RuntimeAssembly.GetExportedTypes()
at System.Web.Http.Dispatcher.DefaultHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver)
at System.Web.Http.WebHost.WebHostHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver)
at System.Web.Http.Dispatcher.HttpControllerTypeCache.InitializeCache()
at System.Lazy
1.CreateValue()
at System.Lazy1.LazyInitValue()
at System.Lazy
1.get_Value()
at System.Web.Http.Dispatcher.DefaultHttpControllerSelector.InitializeControllerInfoCache()
at System.Lazy1.CreateValue()
at System.Lazy
1.LazyInitValue()
at System.Lazy`1.get_Value()
at System.Web.Http.Dispatcher.DefaultHttpControllerSelector.SelectController(HttpRequestMessage request)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)</StackTrace></Exception>

BTW: Here is the code from MVC that is used by the area registration. It simply catches the error and moves on. I'm not sure why WebAPI doesn't do the same thing, or even use the same code.


private static IEnumerable<Type> FilterTypesInAssemblies(Predicate<Type> predicate) {
        // Go through all assemblies referenced by the application and search for types matching a predicate
        IEnumerable<Type> typesSoFar = Type.EmptyTypes;

        ICollection assemblies = BuildManager.GetReferencedAssemblies();
        foreach (Assembly assembly in assemblies) {
            Type[] typesInAsm;
            try {
                typesInAsm = assembly.GetTypes();
            }
            catch (ReflectionTypeLoadException ex) {
                typesInAsm = ex.Types;
            }
            typesSoFar = typesSoFar.Concat(typesInAsm);
        }
        return typesSoFar.Where(type => TypeIsPublicClass(type) && predicate(type));
    }
Closed Jun 10 at 9:29 PM by hongyes
Fixed in RTM

comments

HenrikN wrote Jul 26, 2012 at 12:31 PM

Thanks for the report -- the problem was fixed in this commit [1] and is available in RTM as well as the latest nightly builds.

Thanks,

[1] http://aspnetwebstack.codeplex.com/SourceControl/changeset/07f8232f33af

roncain wrote Jul 26, 2012 at 12:37 PM

This issue was fixed post-RC, much as the way you described.
The fix will be available in the RTM version.

Are you able to work around it until then?

Probably the most common cause of the exception is having an assembly in the bin folder which depends on types in an assembly not in the bin folder. If type B derives from A, and type B's assembly is in bin but A's is not, you will see this kind of exception.