Hi,

I tried taking your example and breaking it down a bit.  I changed the
return type of getUtility to return an ObjRef.  I then did the following
in getUtility():

return( RemotingServices.Marshal(new UtilityClass()) );

Then, on the client side of the fence I unmarshaled to an Object.  The
ObjRef on the client side contains all of the type information as one
would expect since ObjRef is serializable.  However, it fails when one
tries to cast the Object obtained from it into a UtilityClass type.

If you instruct soapsuds to export the metadata into an assembly with the
same name as your server, the problem should go away.  The proxy is trying
to find the assembly that the objref references and it cannot find it.
This is the real problem.  It's not so much a problem with the content
that soapsuds is exporting.

Hope this helps,

   -Trey


> I hope this isn't a basic question. (Something very similar came up last
> year on the list, but didn't get answered. I've also found a couple of
> references on the newsgroup microsoft.public.dotnet.framework.remoting,
> but again there was no answer beyond "I guess it just doesn't work".)
>
> Using a client compiled against a SoapSuds generated proxy, I'm unable
> to invoke any server-side method that returns an instance of another
> server-side class. So, if I write on the client:
>
>      FactoryClass factory = (FactoryClass) Activator.GetObject (...)
> String s = factory.getName();
>      UtilityClass utility = factory.getUtility();
>
> then factory.getName() returns successfully, but factory.getUtility()
> gives an InvalidCastException. (Details below.)
>
> The only way I can get this to work is to compile the client against the
> server's library. If I compile against the proxy generated by SoapSuds,
> it doesn't work.
>
> Does anyone know why this is happening? Is it a bug in SoapSuds, or
> something trivial that I've overlooked? Apologies if it's the latter,
> but I really can't find any refrences that would explain how to solve
> this issue. I'm working through Rammer's "Advanced .NET Remoting" and it
> doesn't seem to have anything to say on the subject.
>
> Thanks,
>
> Alasdair
>
>
> =================================================================
> Source Code
> =================================================================
>
> -----------------------------------------------------------------
> Client.cs
> -----------------------------------------------------------------
> using System;
> using System.Runtime.Remoting;
> using System.Runtime.Remoting.Channels;
> using System.Runtime.Remoting.Channels.Http;
> using Server;
> public class TheClient
> {
>     public static void Main (string[] args)
>     {
>         ChannelServices.RegisterChannel (new HttpChannel());
>         FactoryClass factory = (FactoryClass) Activator.GetObject
>             (typeof
> (FactoryClass),"http://localhost:1095/FactoryClass";);
>         String s = factory.getName();
>         Console.WriteLine("Got name " + s);
>         UtilityClass utility = factory.getUtility();
>     }
> }
>
> -----------------------------------------------------------------
> Server.cs
> -----------------------------------------------------------------
> using System;
> using System.IO;
> using System.Runtime.Remoting;
> using System.Runtime.Remoting.Channels;
> using System.Runtime.Remoting.Channels.Http;
> namespace Server
> {
>     public class UtilityClass : MarshalByRefObject {
>     }
>
>     public class FactoryClass : MarshalByRefObject {
>         public UtilityClass getUtility() {
>             return new UtilityClass();
>         }
>         public String getName() {
>             return "I'm a useful factory";
>         }
>     }
>
>     public class ServerClass
>     {
>         public static void Main ()
>         {
>             ChannelServices.RegisterChannel (new HttpChannel(1095));
> RemotingConfiguration.RegisterWellKnownServiceType(
>                typeof(FactoryClass),"FactoryClass",WellKnownObjectMode.Singleton);
>             Console.WriteLine ("Press enter to stop the server...");
> Console.ReadLine ();
>         }
>     }
> }
>
> -----------------------------------------------------------------
> command line options
> -----------------------------------------------------------------
> This works:
>
>   csc  AJMClient.cs /r:AJMServer.exe
>
> This doesn't
>
>   soapsuds -nowp -ia:AJMServer  -oa:soapsuds.dll
>   csc AJMClient.cs /r:soapsuds.dll
>
> Nor does this:
>
>   soapsuds -nowp -ia:AJMServer  -gc
>   csc AJMClient.cs soapsuds.cs
>
>
> (Note: options "/r:system.runtime.remoting.dll /r:system.dll" omitted
> for clarity)
>
> -----------------------------------------------------------------
> Stack Trace
> -----------------------------------------------------------------
> Unhandled Exception: System.InvalidCastException: Return argument has an
> invalid type.
>    at System.Runtime.Remoting.Proxies.RealProxy.ValidateReturnArg(Object
> arg, Type paramType) at
> System.Runtime.Remoting.Proxies.RealProxy.PropagateOutParameters(IMessage
> msg, Object[] outArgs, Object returnValue) at
> System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
> reqMsg, IMessage retMsg) at
> System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
> msgData, Int32 type) at Server.FactoryClass.getUtility()
>    at TheClient.Main(String[] args) in
> D:\play\dotnet_remoting\ajm\AJMClient.cs:line 14

Reply via email to