2010-05-05 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web / HttpApplication.cs
index a36a0443af0b395cd4ddd7e4113b51d15f55235c..d9972ceddec874d60ed40d8dafba25186e78fad8 100644 (file)
@@ -6,7 +6,7 @@
 //     Gonzalo Paniagua (gonzalo@ximian.com)
 //    
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -73,16 +73,19 @@ using System.Security.Permissions;
 using System.Security.Principal;
 using System.Threading;
 using System.Web.Caching;
+using System.Web.Compilation;
 using System.Web.Configuration;
+using System.Web.Management;
 using System.Web.SessionState;
 using System.Web.UI;
+using System.Web.Util;
 
 #if TARGET_J2EE
 using Mainsoft.Web;
 #endif
        
-namespace System.Web {
-
+namespace System.Web
+{
        // CAS
        [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
@@ -158,7 +161,6 @@ namespace System.Web {
 
                static string binDirectory;
                
-#if NET_2_0
 #if TARGET_J2EE
                const string initialization_exception_key = "System.Web.HttpApplication.initialization_exception";
                static Exception initialization_exception {
@@ -169,7 +171,6 @@ namespace System.Web {
                static Exception initialization_exception;
 #endif
                bool removeConfigurationFromCache;
-#endif
                bool fullInitComplete = false;
                
                //
@@ -201,17 +202,10 @@ namespace System.Web {
                                if (modcoll != null)
                                        return;
                                
-#if NET_2_0
                                HttpModulesSection modules;
                                modules = (HttpModulesSection) WebConfigurationManager.GetWebApplicationSection ("system.web/httpModules");
-#else
-                               ModulesConfiguration modules;
-
-                               modules = (ModulesConfiguration) HttpContext.GetAppConfig ("system.web/httpModules");
-#endif
-
                                HttpContext saved = HttpContext.Current;
-                               HttpContext.Current = new HttpContext (new System.Web.Hosting.SimpleWorkerRequest ("", "", new StringWriter()));
+                               HttpContext.Current = new HttpContext (new System.Web.Hosting.SimpleWorkerRequest (String.Empty, String.Empty, new StringWriter()));
                                modcoll = modules.LoadModules (this);
                                HttpContext.Current = saved;
 
@@ -236,11 +230,9 @@ namespace System.Web {
                        }
                }
 
-#if NET_2_0
                internal static Exception InitializationException {
                        get { return initialization_exception; }
                }
-#endif
 
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
@@ -286,10 +278,10 @@ namespace System.Web {
                public HttpRequest Request {
                        get {
                                if (context == null)
-                                       throw new HttpException (Locale.GetText ("No context is available."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("No context is available."), WebEventCodes.RuntimeErrorRequestAbort);
 
                                if (false == HttpApplicationFactory.ContextAvailable)
-                                       throw new HttpException (Locale.GetText ("Request is not available in this context."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("Request is not available in this context."), WebEventCodes.RuntimeErrorRequestAbort);
 
                                return context.Request;
                        }
@@ -300,10 +292,10 @@ namespace System.Web {
                public HttpResponse Response {
                        get {
                                if (context == null)
-                                       throw new HttpException (Locale.GetText ("No context is available."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("No context is available."), WebEventCodes.RuntimeErrorRequestAbort);
 
                                if (false == HttpApplicationFactory.ContextAvailable)
-                                       throw new HttpException (Locale.GetText ("Response is not available in this context."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("Response is not available in this context."), WebEventCodes.RuntimeErrorRequestAbort);
 
                                return context.Response;
                        }
@@ -333,11 +325,11 @@ namespace System.Web {
                                        return session;
 
                                if (context == null)
-                                       throw new HttpException (Locale.GetText ("No context is available."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("No context is available."), WebEventCodes.RuntimeErrorRequestAbort);
 
                                HttpSessionState ret = context.Session;
                                if (ret == null)
-                                       throw new HttpException (Locale.GetText ("Session state is not available in the context."));
+                                       throw HttpException.NewWithCode (Locale.GetText ("Session state is not available in the context."), WebEventCodes.RuntimeErrorRequestAbort);
                                
                                return ret;
                        }
@@ -345,18 +337,10 @@ namespace System.Web {
 
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
-#if NET_2_0
                public ISite Site {
-#else
-               public virtual ISite Site {
-#endif
-                       get {
-                               return isite;
-                       }
+                       get { return isite; }
 
-                       set {
-                               isite = value;
-                       }
+                       set { isite = value; }
                }
 
                [Browsable (false)]
@@ -548,7 +532,6 @@ namespace System.Web {
                        UpdateRequestCache += new EventHandler (invoker.Invoke);
                }
 
-#if NET_2_0
                static object PostAuthenticateRequestEvent = new object ();
                public event EventHandler PostAuthenticateRequest
                {
@@ -794,8 +777,6 @@ namespace System.Web {
                        AsyncInvoker invoker = new AsyncInvoker (beginHandler, endHandler, state);
                        PostLogRequest += new EventHandler (invoker.Invoke);
                }
-
-#endif
                
                internal event EventHandler DefaultAuthentication;
 
@@ -851,17 +832,33 @@ namespace System.Web {
                {
                }
 
+#if NET_4_0
+               public virtual string GetOutputCacheProviderName (HttpContext context)
+               {
+                       // LAMESPEC: doesn't throw ProviderException if context is null
+                       return OutputCache.DefaultProviderName;
+               }
+#endif
+               
                public virtual string GetVaryByCustomString (HttpContext context, string custom)
                {
                        if (custom == null) // Sigh
                                throw new NullReferenceException ();
 
-                       if (0 == String.Compare (custom, "browser", true, CultureInfo.InvariantCulture))
+                       if (0 == String.Compare (custom, "browser", true, Helpers.InvariantCulture))
                                return context.Request.Browser.Type;
 
                        return null;
                }
 
+               bool ShouldHandleException (Exception e)
+               {
+                       if (e is ParseException)
+                               return false;
+
+                       return true;
+               }
+               
                //
                // If we catch an error, queue this error
                //
@@ -869,15 +866,18 @@ namespace System.Web {
                {
                        bool first = context.Error == null;
                        context.AddError (e);
-                       if (first) {
+                       if (first && ShouldHandleException (e)) {
                                EventHandler eh = nonApplicationEvents [errorEvent] as EventHandler;
                                if (eh != null){
                                        try {
                                                eh (this, EventArgs.Empty);
+                                               if (stop_processing)
+                                                       context.ClearError ();
                                        } catch (ThreadAbortException taex){
                                                context.ClearError ();
-                                               if (FlagEnd.Value == taex.ExceptionState)
-                                                       // This happens on Redirect() or End()
+                                               if (FlagEnd.Value == taex.ExceptionState || HttpRuntime.DomainUnloading)
+                                                       // This happens on Redirect(), End() and
+                                                       // when unloading the AppDomain
                                                        Thread.ResetAbort ();
                                                else
                                                        // This happens on Thread.Abort()
@@ -888,14 +888,13 @@ namespace System.Web {
                                }
                        }
                        stop_processing = true;
-#if NET_2_0
+
                        // we want to remove configuration from the cache in case of 
                        // invalid resource not exists to prevent DOS attack.
                        HttpException httpEx = e as HttpException;
                        if (httpEx != null && httpEx.GetHttpCode () == 404) {
                                removeConfigurationFromCache = true;
                        }
-#endif
                }
                
                //
@@ -934,19 +933,19 @@ namespace System.Web {
                        } catch (ThreadAbortException taex) {
                                object obj = taex.ExceptionState;
                                Thread.ResetAbort ();
-                               stop_processing = true;
                                if (obj is StepTimeout)
-                                       ProcessError (new HttpException ("The request timed out."));
+                                       ProcessError (HttpException.NewWithCode ("The request timed out.", WebEventCodes.RequestTransactionAbort));
                                else {
                                        context.ClearError ();
-                                       if (FlagEnd.Value != obj)
+                                       if (FlagEnd.Value != obj && !HttpRuntime.DomainUnloading)
                                                context.AddError (taex);
                                }
-
+                               
+                               stop_processing = true;
                                PipelineDone ();
                        } catch (Exception e) {
-                               stop_processing = true;
                                ProcessError (e);
+                               stop_processing = true;
                                PipelineDone ();
                        }
                }
@@ -1065,7 +1064,7 @@ namespace System.Web {
                                        if (error is HttpException){
                                                response.StatusCode = ((HttpException)error).GetHttpCode ();
                                        } else {
-                                               error = new HttpException ("", error);
+                                               error = HttpException.NewWithCode (String.Empty, error, WebEventCodes.WebErrorOtherError);
                                                response.StatusCode = 500;
                                        }
                                        HttpException httpEx = (HttpException) error;
@@ -1075,7 +1074,7 @@ namespace System.Web {
                                                response.Flush (true);
                                } else {
                                        if (!(error is HttpException))
-                                               error = new HttpException ("", error);
+                                               error = HttpException.NewWithCode (String.Empty, error, WebEventCodes.WebErrorOtherError);
                                        FinalErrorWrite (response, ((HttpException) error).GetHtmlErrorMessage ());
                                }
                        }
@@ -1109,9 +1108,8 @@ namespace System.Web {
                                        context.Handler = null;
                                        factory = null;
                                }
-#if NET_2_0
                                context.PopHandler ();
-#endif
+
                                // context = null; -> moved to PostDone
                                pipeline = null;
                                current_ai = null;
@@ -1177,9 +1175,22 @@ namespace System.Web {
                        if (stop_processing)
                                yield return true;
 
-#if NET_2_0
-                       context.MapRequestHandlerDone = false;
+#if NET_4_0
+                       if (HttpRequest.ValidateRequestNewMode) {
+                               char[] invalidChars = HttpRequest.RequestPathInvalidCharacters;
+                               HttpRequest req = context.Request;
+                               if (invalidChars != null && req != null) {
+                                       string path = req.PathNoValidation;
+                                       int idx = path != null ? path.IndexOfAny (invalidChars) : -1;
+                                       if (idx != -1)
+                                               throw HttpException.NewWithCode (
+                                                       String.Format ("A potentially dangerous Request.Path value was detected from the client ({0}).", path [idx]),
+                                                       WebEventCodes.RuntimeErrorValidationFailure
+                                               );
+                               }
+                       }
 #endif
+                       context.MapRequestHandlerDone = false;
                        StartTimer ("BeginRequest");
                        eventHandler = Events [BeginRequestEvent];
                        if (eventHandler != null) {
@@ -1201,28 +1212,26 @@ namespace System.Web {
                                        yield return stop;
                        StopTimer ();
 
-#if NET_2_0
                        StartTimer ("PostAuthenticateRequest");
                        eventHandler = Events [PostAuthenticateRequestEvent];
                        if (eventHandler != null)
                                foreach (bool stop in RunHooks (eventHandler))
                                        yield return stop;
                        StopTimer ();
-#endif
+
                        StartTimer ("AuthorizeRequest");
                        eventHandler = Events [AuthorizeRequestEvent];
                        if (eventHandler != null)
                                foreach (bool stop in RunHooks (eventHandler))
                                        yield return stop;
                        StopTimer ();
-#if NET_2_0
+
                        StartTimer ("PostAuthorizeRequest");
                        eventHandler = Events [PostAuthorizeRequestEvent];
                        if (eventHandler != null)
                                foreach (bool stop in RunHooks (eventHandler))
                                        yield return stop;
                        StopTimer ();
-#endif
 
                        StartTimer ("ResolveRequestCache");
                        eventHandler = Events [ResolveRequestCacheEvent];
@@ -1231,7 +1240,6 @@ namespace System.Web {
                                        yield return stop;
                        StopTimer ();
 
-#if NET_2_0
                        StartTimer ("PostResolveRequestCache");
                        eventHandler = Events [PostResolveRequestCacheEvent];
                        if (eventHandler != null)
@@ -1247,7 +1255,6 @@ namespace System.Web {
                                        yield return stop;
                        StopTimer ();
                        context.MapRequestHandlerDone = true;
-#endif
                        
                        StartTimer ("GetHandler");
                        // Obtain the handler for the request.
@@ -1255,22 +1262,27 @@ namespace System.Web {
                        try {
                                handler = GetHandler (context, context.Request.CurrentExecutionFilePath);
                                context.Handler = handler;
-#if NET_2_0
                                context.PushHandler (handler);
-#endif
                        } catch (FileNotFoundException fnf){
 #if TARGET_JVM
                                Console.WriteLine ("$$$$$$$$$$:Sys.Web Pipeline");
                                Console.WriteLine (fnf.ToString ());
 #endif
                                if (context.Request.IsLocal)
-                                       ProcessError (new HttpException (404, String.Format ("File not found {0}", fnf.FileName), fnf, context.Request.FilePath));
+                                       ProcessError (HttpException.NewWithCode (404,
+                                                                                String.Format ("File not found {0}", fnf.FileName),
+                                                                                fnf,
+                                                                                context.Request.FilePath,
+                                                                                WebEventCodes.RuntimeErrorRequestAbort));
                                else
-                                       ProcessError (new HttpException (404, "File not found: " + Path.GetFileName (fnf.FileName), context.Request.FilePath));
+                                       ProcessError (HttpException.NewWithCode (404,
+                                                                                "File not found: " + Path.GetFileName (fnf.FileName),
+                                                                                context.Request.FilePath,
+                                                                                WebEventCodes.RuntimeErrorRequestAbort));
                        } catch (DirectoryNotFoundException dnf){
                                if (!context.Request.IsLocal)
                                        dnf = null; // Do not "leak" real path information
-                               ProcessError (new HttpException (404, "Directory not found", dnf));
+                               ProcessError (HttpException.NewWithCode (404, "Directory not found", dnf, WebEventCodes.RuntimeErrorRequestAbort));
                        } catch (Exception e) {
                                ProcessError (e);
                        }
@@ -1279,14 +1291,12 @@ namespace System.Web {
                        if (stop_processing)
                                yield return true;
 
-#if NET_2_0
                        StartTimer ("PostMapRequestHandler");
                        eventHandler = Events [PostMapRequestHandlerEvent];
                        if (eventHandler != null)
                                foreach (bool stop in RunHooks (eventHandler))
                                        yield return stop;
                        StopTimer ();
-#endif
 
                        StartTimer ("AcquireRequestState");
                        eventHandler = Events [AcquireRequestStateEvent];
@@ -1296,7 +1306,6 @@ namespace System.Web {
                        }
                        StopTimer ();
                        
-#if NET_2_0
                        StartTimer ("PostAcquireRequestState");
                        eventHandler = Events [PostAcquireRequestStateEvent];
                        if (eventHandler != null){
@@ -1304,7 +1313,6 @@ namespace System.Web {
                                        yield return stop;
                        }
                        StopTimer ();
-#endif
                        
                        //
                        // From this point on, we need to ensure that we call
@@ -1325,14 +1333,12 @@ namespace System.Web {
                        bool doProcessHandler = false;
 #endif
                        
-#if NET_2_0
                        IHttpHandler ctxHandler = context.Handler;
                        if (ctxHandler != null && handler != ctxHandler) {
                                context.PopHandler ();
                                handler = ctxHandler;
                                context.PushHandler (handler);
                        }
-#endif
 
                        StartTimer ("ProcessRequest");
                        try {
@@ -1399,14 +1405,12 @@ namespace System.Web {
                        if (stop_processing)
                                yield return true;
 
-#if NET_2_0
                        StartTimer ("PostReleaseRequestState");
                        eventHandler = Events [PostReleaseRequestStateEvent];
                        if (eventHandler != null)
                                foreach (bool stop in RunHooks (eventHandler))
                                        yield return stop;
                        StopTimer ();
-#endif
 
                        StartTimer ("Filter");
                        if (context.Error == null)
@@ -1420,7 +1424,6 @@ namespace System.Web {
                                        yield return stop;
                        StopTimer ();
 
-#if NET_2_0
                        StartTimer ("PostUpdateRequestCache");
                        eventHandler = Events [PostUpdateRequestCacheEvent];
                        if (eventHandler != null)
@@ -1441,7 +1444,7 @@ namespace System.Web {
                                foreach (bool stop in RunHooks (eventHandler))
                                        yield return stop;
                        StopTimer ();
-#endif
+
                        StartTimer ("PipelineDone");
                        PipelineDone ();
                        StopTimer ();
@@ -1450,7 +1453,6 @@ namespace System.Web {
 
                internal CultureInfo GetThreadCulture (HttpRequest request, CultureInfo culture, bool isAuto)
                {
-#if NET_2_0
                        if (!isAuto)
                                return culture;
                        CultureInfo ret = null;
@@ -1465,30 +1467,17 @@ namespace System.Web {
                                ret = culture;
                        
                        return ret;
-#else
-                       return culture;
-#endif
                }
 
 
                void PreStart ()
                {
-#if NET_2_0
                        GlobalizationSection cfg;
                        cfg = (GlobalizationSection) WebConfigurationManager.GetSection ("system.web/globalization");
                        app_culture = cfg.GetCulture ();
                        autoCulture = cfg.IsAutoCulture;
                        appui_culture = cfg.GetUICulture ();
                        autoUICulture = cfg.IsAutoUICulture;
-#else
-                       GlobalizationConfiguration cfg;
-                       cfg = GlobalizationConfiguration.GetInstance (null);
-                       if (cfg != null) {
-                               app_culture = cfg.Culture;
-                               appui_culture = cfg.UICulture;
-                       }
-#endif
-
 #if !TARGET_J2EE
                        context.StartTimeoutTimer ();
 #endif
@@ -1496,14 +1485,14 @@ namespace System.Web {
                        if (app_culture != null) {
                                prev_app_culture = th.CurrentCulture;
                                CultureInfo new_app_culture = GetThreadCulture (Request, app_culture, autoCulture);
-                               if (!new_app_culture.Equals (CultureInfo.InvariantCulture))
+                               if (!new_app_culture.Equals (Helpers.InvariantCulture))
                                        th.CurrentCulture = new_app_culture;
                        }
 
                        if (appui_culture != null) {
                                prev_appui_culture = th.CurrentUICulture;
                                CultureInfo new_app_culture = GetThreadCulture (Request, appui_culture, autoUICulture);
-                               if (!new_app_culture.Equals (CultureInfo.InvariantCulture))
+                               if (!new_app_culture.Equals (Helpers.InvariantCulture))
                                        th.CurrentUICulture = new_app_culture;
                        }
 
@@ -1514,12 +1503,11 @@ namespace System.Web {
 
                void PostDone ()
                {
-#if NET_2_0
                        if (removeConfigurationFromCache) {
                                WebConfigurationManager.RemoveConfigurationFromCache (context);
                                removeConfigurationFromCache = false;
                        }
-#endif
+
                        Thread th = Thread.CurrentThread;
 #if !TARGET_JVM
                        if (Thread.CurrentPrincipal != prev_user)
@@ -1554,10 +1542,8 @@ namespace System.Web {
                        try {
                                InitOnce (true);
                        } catch (Exception e) {
-#if NET_2_0
                                initialization_exception = e;
-#endif
-                               FinalErrorWrite (context.Response, new HttpException ("", e).GetHtmlErrorMessage ());
+                               FinalErrorWrite (context.Response, HttpException.NewWithCode (String.Empty, e, WebEventCodes.RuntimeErrorRequestAbort).GetHtmlErrorMessage ());
                                PipelineDone ();
                                return;
                        }
@@ -1589,7 +1575,7 @@ namespace System.Web {
                        cache.Clear ();
                }
                
-               object LocateHandler (string verb, string url)
+               object LocateHandler (HttpRequest req, string verb, string url)
                {
                        Hashtable cache = GetHandlerCache ();
                        string id = String.Concat (verb, url);
@@ -1597,17 +1583,13 @@ namespace System.Web {
 
                        if (ret != null)
                                return ret;
-                       
-#if NET_2_0
-                       HttpHandlersSection httpHandlersSection = (HttpHandlersSection) WebConfigurationManager.GetWebApplicationSection ("system.web/httpHandlers");
-                       ret = httpHandlersSection.LocateHandler (verb, url);
-#else
-                       HandlerFactoryConfiguration factory_config = (HandlerFactoryConfiguration) HttpContext.GetAppConfig ("system.web/httpHandlers");
-                       ret = factory_config.LocateHandler (verb, url);
-#endif
+
+                       bool allowCache;
+                       HttpHandlersSection httpHandlersSection = WebConfigurationManager.GetSection ("system.web/httpHandlers", req.Path, req.Context) as HttpHandlersSection;
+                       ret = httpHandlersSection.LocateHandler (verb, url, out allowCache);
 
                        IHttpHandler handler = ret as IHttpHandler;
-                       if (handler != null && handler.IsReusable)
+                       if (allowCache && handler != null && handler.IsReusable)
                                cache [id] = ret;
                        
                        return ret;
@@ -1628,10 +1610,9 @@ namespace System.Web {
                        string verb = request.RequestType;
                        
                        IHttpHandler handler = null;
-                       object o = LocateHandler (verb, url);
+                       object o = LocateHandler (request, verb, url);
                        
                        factory = o as IHttpHandlerFactory;
-                       
                        if (factory == null) {
                                handler = (IHttpHandler) o;
                        } else {
@@ -1731,15 +1712,7 @@ namespace System.Web {
                        if (!context.IsCustomErrorEnabledUnsafe)
                                return false;
                        
-#if NET_2_0
-                       CustomErrorsSection config = (CustomErrorsSection)WebConfigurationManager.GetSection ("system.web/customErrors");
-#else
-                       CustomErrorsConfig config = null;
-                       try {
-                               config = (CustomErrorsConfig) context.GetConfig ("system.web/customErrors");
-                       } catch { }
-#endif
-                       
+                       CustomErrorsSection config = (CustomErrorsSection)WebConfigurationManager.GetSection ("system.web/customErrors");                       
                        if (config == null) {
                                if (context.ErrorPage != null)
                                        return RedirectErrorPage (context.ErrorPage);
@@ -1747,12 +1720,8 @@ namespace System.Web {
                                return false;
                        }
                        
-#if NET_2_0
                        CustomError err = config.Errors [context.Response.StatusCode.ToString()];
                        string redirect = err == null ? null : err.Redirect;
-#else
-                       string redirect =  config [context.Response.StatusCode];
-#endif
                        if (redirect == null) {
                                redirect = context.ErrorPage;
                                if (redirect == null)
@@ -1765,7 +1734,7 @@ namespace System.Web {
                        return RedirectErrorPage (redirect);
                        }
                        catch (Exception ex) {
-                               httpEx = new HttpException (500, "", ex);
+                               httpEx = HttpException.NewWithCode (500, String.Empty, ex, WebEventCodes.WebErrorOtherError);
                                return false;
                        }
                }
@@ -1830,7 +1799,6 @@ namespace System.Web {
                                        return type;
                        }
 
-#if NET_2_0
                        IList tla = System.Web.Compilation.BuildManager.TopLevelAssemblies;
                        if (tla != null && tla.Count > 0) {
                                foreach (Assembly asm in tla) {
@@ -1841,24 +1809,54 @@ namespace System.Web {
                                                return type;
                                }
                        }
-#endif
 
-                       type = LoadTypeFromBin (typeName);
+                       Exception loadException = null;
+                       try {
+                               type = null;
+                               type = LoadTypeFromBin (typeName);
+                       } catch (Exception ex) {
+                               loadException = ex;
+                       }
+                       
                        if (type != null)
                                return type;
 #endif
                        if (throwOnMissing)
-                               throw new TypeLoadException (String.Format ("Type '{0}' cannot be found", typeName));
+                               throw new TypeLoadException (String.Format ("Type '{0}' cannot be found", typeName), loadException);
                        
                        return null;
                }
 
+               internal static Type LoadType <TBaseType> (string typeName, bool throwOnMissing)
+               {
+                       Type ret = LoadType (typeName, throwOnMissing);
+
+                       if (typeof (TBaseType).IsAssignableFrom (ret))
+                               return ret;
+
+                       if (throwOnMissing)
+                               throw new TypeLoadException (String.Format ("Type '{0}' found but it doesn't derive from base type '{1}'.", typeName, typeof (TBaseType)));
+
+                       return null;
+               }
+               
                internal static Type LoadTypeFromBin (string typeName)
                {
                        Type type = null;
                        
                        foreach (string s in BinDirectoryAssemblies) {
-                               Assembly binA = Assembly.LoadFrom (s);
+                               Assembly binA = null;
+                               
+                               try {
+                                       binA = Assembly.LoadFrom (s);
+                               } catch (FileLoadException) {
+                                       // ignore
+                                       continue;
+                               } catch (BadImageFormatException) {
+                                       // ignore
+                                       continue;
+                               }
+                               
                                type = binA.GetType (typeName, false);
                                if (type == null)
                                        continue;