Last week at Guerilla
.NET in London, I was talking to one of the students, who was a
Microsoft Consultant, about a remoting problem he had been involved in. The
problem occurred when using the HTTP channel and the
BinaryFormatter, when ASP.NET was hosting the remote component instead of
the server side HTTP channel. The client side channel was unable to interpret
certain types of failures (such as timeouts) and so was passing the resulting
text or HTML to the BinaryFormatter who attempted to interpret the text as
though it were a binary encoded message. This resulted in a weird
SerializationException about formatter version mismatches -
Ingo talks about this issue in his remoting FAQ. This makes it very
difficult to diagnose the actual error without using a tool such as Simon
Fell's TcpTrace.
Now I had never seen this bug - which is strange considering how often my demos
go South - so it was all the more surprising when I hit it the very next day
when delivering the remoting session. I explained to the sudents what the issue
was and that Microsoft had stated that they were unlikely to fix it. Then one
of the students asked whether it could be overcome b y intercepting the call
before the BinaryFormatter sees it - inspired!
The remoting architecture is very pluggable and you can write interception code
and place it wither before or after the formatter in the remoting pipeline. So
I created what is known as a Channel Sink to lie in-between the formatter and
the channel such that it would see the reponse before the formatter. This is
achieved via a configuration file that looks as follows:
<configuration>
<system.runtime.remoting>
<application name="Client">
<channels>
<channel ref="http">
<clientProviders>
<formatter ref="binary"/>
<provider type="DevelopMentor.Runtime.Remoting.HttpErrorMessageSinkProvider, HttpErrorMessageSinkLib"
useHeaders="false">
<matchString data="System.Runtime.Serialization.SerializationException"/>
</provider>
</clientProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
Notice the provider comes after the formatter. This channel sink checks to see
if the returned message is a binary encoded message or some other error that
the BinaryFormatter won't be able to handle. If it sees this sort of error then
it throws a RemotingException containing the response - thus allowing diagnosis
without a network trace.
You can download the sink (along with usage instructions)
here.