.NET Remoting - Changes for .NET 1.1 / Visual Studio 2003
With the introduction of version 1.1 of the .NET Framework, a number of Remoting-related changes have been made. Most of them are focused at increasing security of .NET applications and I therefore consider them A Good Thing. Unfortunately though, they broke a number of samples in my books (and in all the other Remoting books out there).
If you use client activated objects, events or delegates you will quite likely encounter one of the following exceptions when running on the .NET Framework 1.1:
System.Security.SecurityException.
Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this security level.
System.Runtime.Serialization.SerializationException
Because of security restrictions, the type System.Runtime.Remoting.ObjRef cannot be accessed.
To change the security level to allow passing of delegates and object references over Remoting boundaries, you have to change the so called "typeFilterLevel".
You can do this either by using a configuration file like this (for server side):
<configuration>
<system.runtime.remoting>
<channel ref="http" port="1234">
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
<clientProviders>
<formatter ref="binary" />
</clientProviders>
</channel>
<service>
<!-- ... Add your services here ... -->
</service>
</system.runtime.remoting>
</configuration>
In this case, a matching client-side configuration file which allows the reception of events and callbacks, would look like this:
<configuration>
<system.runtime.remoting>
<channel ref="http" port="0">
<clientProviders>
<formatter ref="binary" />
</clientProviders>
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
<client>
<!-- ... Add your classes here ... -->
</client>
</system.runtime.remoting>
</configuration>
If you prefer to setup your channels in source code, you have to use the extended constructor of the HttpChannel or TcpChannel to pass a custom IFormatterSinkProvider object:
BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider();
IDictionary props = new Hashtable();
props["port"] = 1234;
HttpChannel chan = new HttpChannel(props, clientProv, provider);
ChannelServices.RegisterChannel( chan );