Bug 3050 - Objects with Generic Dictionary throw "Object must implement IConvertible." when remoting cross platform
Summary: Objects with Generic Dictionary throw "Object must implement IConvertible." w...
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: System (show other bugs)
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-01-24 16:59 UTC by chris.derrick
Modified: 2016-10-21 10:20 UTC (History)
7 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 3050 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
NEW

Description chris.derrick 2012-01-24 16:59:43 UTC
On Mono 2.6.7 my code works great, I tried running it on 2.10.5 and it looks like I can no longer send an Object containing a Generic Dictionary through remoting from a Linux machine to Windows.  Now it throws an "Object must implement IConvertible." exception.  It however still works correctly when the client and server are on Linux, or when both are on a Windows machine.

I wrote a simple program to illustrate the issue.  The program shows that sending a generic dictionary through remoting works fine if it is not encapsulated within another object, but when it tries to send an object with a generic dictionary inside "Object must implement IConvertible." is thrown when a Windows client tries to get a GenericDictionaryWrapper object from a Linux machine.


--Server Code (running on Linux)--

using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

class Program
{
	static void Main(string[] args)
	{
		Server();
	}
	
	static void Server()
	{
		Console.WriteLine("Server Started");
		
		TcpChannel tcpChannel = new TcpChannel(9998);
		ChannelServices.RegisterChannel(tcpChannel, false);
		
		Type commonInterfaceType = Type.GetType("RemoteClass");
		
		RemotingConfiguration.RegisterWellKnownServiceType(commonInterfaceType,
		"RemotingTest", WellKnownObjectMode.SingleCall);
		
		System.Console.WriteLine("Press ENTER to stop the server");
		System.Console.ReadLine();
	}
}

[Serializable]
public class GenericDictionaryWrapper
{
	public GenericDictionaryWrapper() { }

    private Dictionary<string, object> m_properties = new Dictionary<string, object>();
}

//private Dictionary<string, object> m_properties = new Dictionary<string, object>();
public interface RemotingInterface
{
	string ModifyString(string message);
	Dictionary<string, object> ModifyGenericDictionary(Dictionary<string, object> genericDictionary);
	GenericDictionaryWrapper GetGenericDictionaryWrapper();
}

public class RemoteClass : MarshalByRefObject, RemotingInterface
{
	public string ModifyString(string message)
	{		
		return message.ToUpper();
	}
	
	public Dictionary<string, object> ModifyGenericDictionary(Dictionary<string, object> genericDictionary)
	{
		genericDictionary.Add("addition", "new message");// WORKS
		//genericDictionary.Add("addition", new GenericDictionaryWrapper());// FAILS
		return genericDictionary;
	}
	
	public GenericDictionaryWrapper GetGenericDictionaryWrapper()
	{
		return new GenericDictionaryWrapper();
	}
}


--Client Code (Running on Windows)--

using System;
using System.Collections.Generic;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

class MyClient
{
	public static void Main()
	{
		TcpChannel tcpChannel = new TcpChannel();
		ChannelServices.RegisterChannel(tcpChannel, false);
		
		Type remoteType = typeof(RemotingInterface);
		
		RemotingInterface remoteObject = (RemotingInterface)Activator.GetObject(remoteType,
		"tcp://localhost:9998/RemotingTest");
		
		string message = "The original message";
		Console.WriteLine("The Message: "+message);
		Console.WriteLine("Has Become: "+ remoteObject.ModifyString(message));
		
		Dictionary<string, object> genericDictionary = new Dictionary<string, object>();
		genericDictionary.Add("NewMessage", message);
		genericDictionary = remoteObject.ModifyGenericDictionary(genericDictionary);
		Console.WriteLine("Successfully Modified Generic Dictionary:");
		foreach(object obj in genericDictionary.Values)
		{
			Console.WriteLine("\t"+obj.ToString());
		}
		
		Console.WriteLine("Getting A GenericDictionaryWrapper");
		//This next line is where the error is thrown
		GenericDictionaryWrapper dictionary = remoteObject.GetGenericDictionaryWrapper();
		Console.WriteLine("Successfully Got A GenericDictionaryWrapper");
		
		Console.WriteLine("All Tests Completed Successfully");
	}
}


Note: The Client code depends on the Server code (so it knows about the remotely accessible methods and the GenericDictionaryWrapper object).  So you need to reference the server's executable, I just built both executables on both machines to simplify this.
Comment 1 chris.derrick 2012-01-24 17:34:41 UTC
Others have experienced this issue as well, but as far as I could tell they never actually logged the bug:

http://www.smuxi.org/issues/show/589
Comment 2 Zoltan Varga 2012-01-25 01:13:05 UTC
-> class libs.
Comment 3 Bartek 2012-08-26 06:53:05 UTC
The problem still exists in Mono 2.10.8.1 running on Ubuntu 
(Mono JIT compiler version 2.10.8.1 Debian 2.10.8.1-1ubuntu2.2)

I've tested this sample code: 
* Running both server and client on Windows: OK
* Running both server and client on Linux Ubuntu (): OK
* Running server on Ubuntu and client on Windows -> Object must implement IConvertible exception

Note: In the sample code I've uncommented section marked as 'FAILS'
Comment 4 dennis 2013-01-10 16:17:30 UTC
I can confirm this issue, too.

Server: (Linux)
$ mono --version
Mono JIT compiler version 3.0.2 (tarball Fri Dec  7 21:53:57 UTC 2012)
Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  x86
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            Included Boehm (with typed GC and Parallel Mark)


Client: (Windows)
.Net Runtime v4.0.30319
same with .Net Runtime v2.0.50727