X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Web%2FSystem.Web%2FHttpApplication.cs;h=d9972ceddec874d60ed40d8dafba25186e78fad8;hb=c1b39535fe0d5d1771b18f305a4d453ee944e04c;hp=30b782b2565cf015be2162edb35d093168341ed8;hpb=82a1631ac4ccb2c0d8ae97acb5aa2821430bb9f5;p=mono.git diff --git a/mcs/class/System.Web/System.Web/HttpApplication.cs b/mcs/class/System.Web/System.Web/HttpApplication.cs index 30b782b2565..d9972ceddec 100644 --- a/mcs/class/System.Web/System.Web/HttpApplication.cs +++ b/mcs/class/System.Web/System.Web/HttpApplication.cs @@ -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.GetSection ("system.web/httpModules", HttpRuntime.AppDomainAppVirtualPath); -#else - ModulesConfiguration modules; - - modules = (ModulesConfiguration) HttpContext.GetAppConfig ("system.web/httpModules"); -#endif - + modules = (HttpModulesSection) WebConfigurationManager.GetWebApplicationSection ("system.web/httpModules"); 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 ()); } } @@ -1097,6 +1096,9 @@ namespace System.Web { try { OutputPage (); + } catch (ThreadAbortException taex) { + ProcessError (taex); + Thread.ResetAbort (); } catch (Exception e) { Console.WriteLine ("Internal error: OutputPage threw an exception " + e); } finally { @@ -1106,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; @@ -1122,7 +1123,48 @@ namespace System.Web { requests_total_counter.Increment (); } - + + class Tim { + string name; + DateTime start; + + public Tim () { + } + + public Tim (string name) { + this.name = name; + } + + public string Name { + get { return name; } + set { name = value; } + } + + public void Start () { + start = DateTime.UtcNow; + } + + public void Stop () { + Console.WriteLine ("{0}: {1}ms", name, (DateTime.UtcNow - start).TotalMilliseconds); + } + } + + Tim tim; + [Conditional ("PIPELINE_TIMER")] + void StartTimer (string name) + { + if (tim == null) + tim = new Tim (); + tim.Name = name; + tim.Start (); + } + + [Conditional ("PIPELINE_TIMER")] + void StopTimer () + { + tim.Stop (); + } + // // Events fired as described in `Http Runtime Support, HttpModules, // Handling Public Events' @@ -1133,115 +1175,157 @@ namespace System.Web { if (stop_processing) yield return true; +#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) { foreach (bool stop in RunHooks (eventHandler)) yield return stop; } + StopTimer (); + StartTimer ("AuthenticateRequest"); eventHandler = Events [AuthenticateRequestEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) yield return stop; + StopTimer (); + StartTimer ("DefaultAuthentication"); if (DefaultAuthentication != null) foreach (bool stop in RunHooks (DefaultAuthentication)) 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; -#endif + StopTimer (); + + StartTimer ("AuthorizeRequest"); eventHandler = Events [AuthorizeRequestEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) yield return stop; -#if NET_2_0 + StopTimer (); + + StartTimer ("PostAuthorizeRequest"); eventHandler = Events [PostAuthorizeRequestEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) yield return stop; -#endif + StopTimer (); + StartTimer ("ResolveRequestCache"); eventHandler = Events [ResolveRequestCacheEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) yield return stop; + StopTimer (); -#if NET_2_0 + StartTimer ("PostResolveRequestCache"); eventHandler = Events [PostResolveRequestCacheEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) yield return stop; + StopTimer (); + StartTimer ("MapRequestHandler"); // As per http://msdn2.microsoft.com/en-us/library/bb470252(VS.90).aspx eventHandler = Events [MapRequestHandlerEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) yield return stop; -#endif + StopTimer (); + context.MapRequestHandlerDone = true; + StartTimer ("GetHandler"); // Obtain the handler for the request. IHttpHandler handler = null; 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); } + StopTimer (); 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; -#endif + StopTimer (); + StartTimer ("AcquireRequestState"); eventHandler = Events [AcquireRequestStateEvent]; if (eventHandler != null){ foreach (bool stop in RunHooks (eventHandler)) yield return stop; } + StopTimer (); -#if NET_2_0 + StartTimer ("PostAcquireRequestState"); eventHandler = Events [PostAcquireRequestStateEvent]; if (eventHandler != null){ foreach (bool stop in RunHooks (eventHandler)) yield return stop; } -#endif + StopTimer (); // // From this point on, we need to ensure that we call // ReleaseRequestState, so the code below jumps to // `release:' to guarantee it rather than yielding. // + StartTimer ("PreRequestHandlerExecute"); eventHandler = Events [PreRequestHandlerExecuteEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) if (stop) goto release; + StopTimer (); #if TARGET_J2EE @@ -1249,15 +1333,14 @@ 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 { context.BeginTimeoutPossible (); if (handler != null){ @@ -1282,6 +1365,7 @@ namespace System.Web { in_begin = false; context.EndTimeoutPossible (); } + StopTimer (); #if TARGET_J2EE if (doProcessHandler) { yield return false; @@ -1295,13 +1379,16 @@ namespace System.Web { // These are executed after the application has returned + StartTimer ("PostRequestHandlerExecute"); eventHandler = Events [PostRequestHandlerExecuteEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) if (stop) goto release; + StopTimer (); release: + StartTimer ("ReleaseRequestState"); eventHandler = Events [ReleaseRequestStateEvent]; if (eventHandler != null){ #pragma warning disable 219 @@ -1313,48 +1400,59 @@ namespace System.Web { } #pragma warning restore 219 } + StopTimer (); 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; -#endif + StopTimer (); + StartTimer ("Filter"); if (context.Error == null) context.Response.DoFilter (true); + StopTimer (); + StartTimer ("UpdateRequestCache"); eventHandler = Events [UpdateRequestCacheEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) yield return stop; + StopTimer (); -#if NET_2_0 + StartTimer ("PostUpdateRequestCache"); eventHandler = Events [PostUpdateRequestCacheEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) yield return stop; + StopTimer (); + StartTimer ("LogRequest"); eventHandler = Events [LogRequestEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) yield return stop; + StopTimer (); + StartTimer ("PostLogRequest"); eventHandler = Events [PostLogRequestEvent]; if (eventHandler != null) foreach (bool stop in RunHooks (eventHandler)) yield return stop; -#endif + StopTimer (); + + StartTimer ("PipelineDone"); PipelineDone (); + StopTimer (); } internal CultureInfo GetThreadCulture (HttpRequest request, CultureInfo culture, bool isAuto) { -#if NET_2_0 if (!isAuto) return culture; CultureInfo ret = null; @@ -1369,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 @@ -1400,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; } @@ -1418,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) @@ -1458,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; } @@ -1493,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); @@ -1501,17 +1583,13 @@ namespace System.Web { if (ret != null) return ret; - -#if NET_2_0 - HttpHandlersSection httpHandlersSection = (HttpHandlersSection) WebConfigurationManager.GetSection ("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; @@ -1532,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 { @@ -1635,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); @@ -1651,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) @@ -1669,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; } } @@ -1734,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) { @@ -1745,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 (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;