>>>> 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