>>>> Test programs for Bug #24957 MySql.Data.Types.MySqlConversionException is not marked as Serializable >>>>>>>>>>>>>>>>>> Part 1 - Remote assembly <<<<<<<<<<<<<<<<<<<<<< Save as MySQLRemoteTest.cs and compile first using: csc /r:MySql.Data.dll /out:MySQLRemoteTest.dll /target:library MySQLRemoteTest.cs // Start MySQLRemoteTest.cs using System; using System.Threading; using System.Runtime.Serialization; using MySql.Data.Types; namespace MySQLExceptionTest { /// /// Remote test class. /// public class ThrowException: MarshalByRefObject { public ThrowException() { } /// /// Throw the specified test exception. /// /// True to use the exception that handles serialization; false to use the standard MySqlConversionException. public void ThrowIt(bool useFix) { Console.WriteLine("In the application domain: " + Thread.GetDomain().FriendlyName); if(useFix) throw new MySqlConversionExceptionFix("Fix Test Message"); else throw new MySqlConversionException("Test Message"); } } /// /// Implementation of MySqlCon.versionException that will handle remoting /// correctly. /// /// For guidelines regarding the creation of new exception types, see /// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp /// and /// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp /// [Serializable] public class MySqlConversionExceptionFix: ApplicationException { public MySqlConversionExceptionFix() { } public MySqlConversionExceptionFix(string message) : base(message) { } public MySqlConversionExceptionFix(string message, Exception inner) : base(message, inner) { } /// /// Serialization constructor. /// protected MySqlConversionExceptionFix(SerializationInfo info, StreamingContext context) : base(info, context) { } } } // End MySQLRemoteTest.cs >>>>>>>>>>>>>>>>>> Part 2 - Client program <<<<<<<<<<<<<<<<<<<<<< Save as MySQLExceptionTest.cs and compile using: csc /r:MySql.Data.dll,MySQLRemoteTest.dll /out:MySQLExceptionTest.exe /target:exe MySQLExceptionTest.cs // Start MySQLExceptionTest.cs using System; using System.Collections.Generic; using System.Text; using MySql.Data.Types; using System.Reflection; using System.Runtime.Remoting; namespace MySQLExceptionTest { public class Program { public static void Main(String[] argv) { // Create our test class and call the test methods... ExceptionTest test = new ExceptionTest(); test.BugTest(); test.FixTest(); test.Dispose(); } } public class ExceptionTest : IDisposable { private ThrowException _remoteInstance; private AppDomain _remoteDomain; private string _divider = new string('-', 80); /// /// Call the remote method and tell it to throw MySqlConversionException. /// We should catch the MySqlConversionException, however, because it doesn't /// handle serialization, we get a different exception. /// public void BugTest() { Console.WriteLine(_divider); Console.WriteLine(" Test using MySqlConversionException"); Console.WriteLine(_divider); try { // Invoke the method _remoteInstance.ThrowIt(false); Console.WriteLine("No exception occured in remote method."); } catch(MySqlConversionException cnvEx) { Console.WriteLine("MySqlConversionException occured in remote method. Message: {0}", cnvEx.Message); } catch(Exception ex) { Console.WriteLine("Other occured in remote method. Details: {0}", ex); } } /// /// Call the remote method and tell it to throw MySqlConversionExceptionFix, which /// is basically MySqlConversionException with the [Serializable] attribute and /// a serialization constructor. /// This time we catch correct exception. /// public void FixTest() { Console.WriteLine(_divider); Console.WriteLine(" Test using with Serialization fix"); Console.WriteLine(_divider); try { // Invoke the method _remoteInstance.ThrowIt(true); Console.WriteLine("No exception occured in remote method."); } catch(MySqlConversionExceptionFix cnvEx) { Console.WriteLine("MySqlConversionExceptionFix occured in remote method. Message: {0}", cnvEx.Message); } catch(Exception ex) { Console.WriteLine("Other occured in remote method. Details: {0}", ex); } } /// /// Set up another application domain so calls to objects created in it will /// be marshalled across the domain boundry using serialization. /// public ExceptionTest() { // Set ApplicationBase to the current directory AppDomainSetup info = new AppDomainSetup(); info.ApplicationBase = "file:///" + System.Environment.CurrentDirectory; // Create an application domain with null evidence _remoteDomain = AppDomain.CreateDomain("RemoteDomain", null, info); // Load the MySQLRemoteTest assembly and instantiate the type // MySQLExceptionTest.ThrowException BindingFlags flags = (BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance); ObjectHandle objh = _remoteDomain.CreateInstance("MySQLRemoteTest", "MySQLExceptionTest.ThrowException", false, flags, null, new object[] { }, null, null, null); if(objh == null) { Console.WriteLine("CreateInstance failed"); return; } // Unwrap the object Object obj = objh.Unwrap(); // Cast to the actual type _remoteInstance = (ThrowException)obj; } /// /// Clean up by unloading the application domain /// public void Dispose() { AppDomain.Unload(_remoteDomain); } } } // End MySQLExceptionTest.cs