Dva nejčastější dotazy k .NET Remotingu
V diskuzních fórech se objevuje mnoho dotazů k .NET Remotingu, ale následující dva jsou evergreenem. Těm z Vás, kdo záludnosti .Net Remotingu ještě neodhalili sami, nabízím řešení a doufám, že dotazů ve fórech ubude.:)
V .Net Frameworku 1.1 dojde při pokusu o komunikaci se vzdáleným objektem k výjimce SecurityException nebo SerializationException. V .Net Frameworku 1.0 aplikace funguje bez problémů.
.Net Framework 1.1 z bezpečnostních důvodů nepovoluje ve výchozí konfiguraci deserializaci všech typů, takže k výjimce dojde například při předání potomka třídy MarshalByRefObject z klienta na server nebo při registraci delegáta k události. Řešením je nastavit u objektu formatter, který provádí (de)serializaci, že povolujeme deserializaci všech typů. Úroveň deserializace vyjadřuje enumerace TypeFilterLevel a chování shodného s verzí 1.0 dosáhneme použitím hodnoty Full. Hodnotu Full přiřadíme objektu formatter (přesněji poskytovateli objektu formatter) v konfiguračním souboru nebo přímo v kódu. Nastavení úrovně full musí být provedeno na serveru a když používáte zpětná volání (callback) nebo události, tak musíte úroveň Full nastavit i na klientovi. Nezapomeňte, že byste měli zprávy mezi klientem a serverem přenášet přes https nebo je alespoň kryptovat.
Nastavení v konfiguračním souboru
Server
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel ref="http" port="7777">
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
Klient
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel ref="http" port="0">
<clientProviders>
<formatter ref="binary" />
</clientProviders>
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
Nastavení v kódu
BinaryServerFormatterSinkProvider binProvider = new BinaryFormatterSinkProvider();
binProvider.TypeFilterLevel = TypeFilterLevel.Full;
SoapServerFormatterSinkProvider soapProvider = new SoapServerFormatterSinkProvider();
soapProvider.TypeFilterLevel = TypeFilterLevel.Full;
Za další otázkou se skrývá záludnější problém. Při použití http kanálu, binárního formatteru (formátovač mi nějak do pera nejde) a hostování vzdáleného objektu v IIS dostanete na klientovi občas následující výjimku.
An unhandled exception of type 'System.Runtime.Serialization. SerializationException' occurred in mscorlib.dll
Additional information: BinaryFormatter Version incompatibility. Expected Version 1.0. Received Version <nesmyslné číslo>
Matoucí je hlavně nesmyslné číslo na konci, které zcela evidentně nepředstavuje žádnou známou verzi formatteru a tedy nelze jednoduše nalézt pravou příčinu nepovedené deserializace. Vysvětlení je prosté - došlo k chybě na úrovni IIS a klientovi se vrátí chybové http hlášení (například HTTP/1.1 500 Internal server error), protože WWW server/vzdálený objekt není z nějakého důvodu dostupný. Bohužel formatter se snaží nalézt v této zprávě hlavičku s verzí formatteru použitého na serveru a protože ji nalézt nemůže, vyhodí matoucí hlášku, že našel nesmyslnou verzi, jejíž číslo vezme bůhvíkde.
Pastí je v .Net Remotingu více, klidně mi napište, s jakými problémy jste se setkali vy, a já připravím pokračování poradny:)
Sunday, 02 May 2004 18:08:00 (Central Europe Standard Time, UTC+01:00)
.Net Remoting