\


 Sunday, 02 May 2004
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)       
Comments [0]  .Net Remoting