// 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
using System.Collections;
using System.ComponentModel;
using System.Configuration;
+using System.Diagnostics;
using System.Globalization;
using System.Reflection;
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)]
static readonly object disposedEvent = new object ();
static readonly object errorEvent = new object ();
+ // we do this static rather than per HttpApplication because
+ // mono's perfcounters use the counter instance parameter for
+ // the process to access shared memory.
+ internal static PerformanceCounter requests_total_counter = new PerformanceCounter ("ASP.NET", "Requests Total");
+
internal static readonly string [] BinDirs = {"Bin", "bin"};
object this_lock = new object();
static string binDirectory;
-#if NET_2_0
#if TARGET_J2EE
const string initialization_exception_key = "System.Web.HttpApplication.initialization_exception";
static Exception initialization_exception {
static Exception initialization_exception;
#endif
bool removeConfigurationFromCache;
-#endif
bool fullInitComplete = false;
//
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;
}
}
-#if NET_2_0
internal static Exception InitializationException {
get { return initialization_exception; }
}
-#endif
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
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;
}
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;
}
return session;
if (context == null)
- throw new HttpException (Locale.GetText ("No context is available."));
- return context.Session;
+ throw HttpException.NewWithCode (Locale.GetText ("No context is available."), WebEventCodes.RuntimeErrorRequestAbort);
+
+ HttpSessionState ret = context.Session;
+ if (ret == null)
+ throw HttpException.NewWithCode (Locale.GetText ("Session state is not available in the context."), WebEventCodes.RuntimeErrorRequestAbort);
+
+ return ret;
}
}
[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)]
UpdateRequestCache += new EventHandler (invoker.Invoke);
}
-#if NET_2_0
static object PostAuthenticateRequestEvent = new object ();
public event EventHandler PostAuthenticateRequest
{
AsyncInvoker invoker = new AsyncInvoker (beginHandler, endHandler, state);
PostLogRequest += new EventHandler (invoker.Invoke);
}
-
-#endif
internal event EventHandler DefaultAuthentication;
{
}
+#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
//
{
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()
}
}
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
}
//
} 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 ();
}
}
void async_handler_complete_cb (IAsyncResult ar)
{
- IHttpAsyncHandler async_handler = ((IHttpAsyncHandler) ar.AsyncState);
+ IHttpAsyncHandler async_handler = ar != null ? ar.AsyncState as IHttpAsyncHandler : null;
try {
- async_handler.EndProcessRequest (ar);
+ if (async_handler != null)
+ async_handler.EndProcessRequest (ar);
} catch (Exception e){
ProcessError (e);
}
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;
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 ());
}
}
try {
OutputPage ();
+ } catch (ThreadAbortException taex) {
+ ProcessError (taex);
+ Thread.ResetAbort ();
} catch (Exception e) {
Console.WriteLine ("Internal error: OutputPage threw an exception " + e);
} finally {
context.Handler = null;
factory = null;
}
-#if NET_2_0
context.PopHandler ();
-#endif
+
// context = null; -> moved to PostDone
pipeline = null;
current_ai = null;
begin_iar.Complete ();
else
done.Set ();
+
+ 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'
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
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){
in_begin = false;
context.EndTimeoutPossible ();
}
+ StopTimer ();
#if TARGET_J2EE
if (doProcessHandler) {
yield return false;
// 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
}
#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;
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
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;
}
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)
context = HttpContext.Current;
context.StopTimeoutTimer ();
#endif
+ context.Request.ReleaseResources ();
+ context.Response.ReleaseResources ();
context = null;
session = null;
HttpContext.Current = null;
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;
}
cache.Clear ();
}
- internal object LocateHandler (string verb, string url)
+ object LocateHandler (HttpRequest req, string verb, string url)
{
Hashtable cache = GetHandlerCache ();
string id = String.Concat (verb, url);
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
- cache [id] = ret;
+ 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 (allowCache && handler != null && handler.IsReusable)
+ cache [id] = ret;
+
return ret;
}
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 {
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);
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)
return RedirectErrorPage (redirect);
}
catch (Exception ex) {
- httpEx = new HttpException (500, "", ex);
+ httpEx = HttpException.NewWithCode (500, String.Empty, ex, WebEventCodes.WebErrorOtherError);
return false;
}
}
return type;
}
-#if NET_2_0
IList tla = System.Web.Compilation.BuildManager.TopLevelAssemblies;
if (tla != null && tla.Count > 0) {
foreach (Assembly asm in tla) {
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;