Strange.NET remoting SerializationException with MarshalByRefObject

I have a delete problem in my application. Since the architecture is quite complex, I will try to make a simple example with the names of dummy elements to illustrate the problem.

Consider these components:

  • MyApp.Client.exe: client application
  • MyApp.Service.exe: the Windows service on which the server is hosted.
  • MyApp.Server.dll: server implementation
  • MyApp.Shared.dll: a shared library containing common definitions of interfaces and types

In MyApp.Shared.dll, I have the following interfaces:

public interface IFoo
{
    ...
}

public interface IFooManager
{
    IList<IFoo> GetFooList();
    ...
}

Both interfaces are implemented in MyApp.Server.dll as MarshalByRefObjects:

class Foo : MarshalByRefObject, IFoo
{
    ...
}

class FooManager : MarshalByRefObject, IFooManager
{
    public IList<IFoo> GetFooList()
    {
        IList<IFoo> foos = new List<IFoo>();
        // populate the list with instances of Foo
        // ...
        return foos;
    }

    ...
}

- FooManager . GetFooList , , FooManager.GetFooList() , , SerializationException:

Unable to find assembly 'MyApp.Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

Server stack trace: 
   at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
   at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
   at System.Runtime.Serialization.Formatters.Binary.ObjectMap.Create(String name, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryResponseMessage(Stream inputStream, IMethodCallMessage reqMsg, Boolean bStrictBinding)
   at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream)
   at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at MyApp.Shared.IFooManager.GetFooList()
   ...
   at MyApp.Client.ViewModel.MainWindowViewModel.LoadFoos()
   ...

, , Foo ( , GetFooList ) , Foo. ? Foo MarshalByRefObject, - Foo? , IFoo , MyApp.Server.dll...

, , MyApp.Server.dll, , AppDomain ( ). , ...

- , ? (, )? ...

+3
3

, , , IFoo , .

shared.dll

namespace Shared
{
    public interface IFoo
    {
        string Name{get;set;}
    }

    public interface IFooMgr {
        IList<IFoo> GetList();
    }
}

Foo, :

namespace Server
{
    public class Foo : MarshalByRefObject, IFoo
    {
        public string Name
        {
            get;set;
        }
    }

    public class FooManager :  MarshalByRefObject, IFooMgr
    {
        public IList<IFoo> GetList()
        {
            IList<IFoo> fooList = new List<IFoo>();
            fooList.Add(new Foo { Name = "test" });
            fooList.Add(new Foo { Name = "test2" });
            return fooList;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ChannelServices.RegisterChannel(new TcpChannel(1237),true);
            System.Runtime.Remoting.RemotingServices.Marshal(new FooManager(),
               "FooManager");
            Console.Read();
        }
    }
}

, , , , appdomain server.exe:

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpChannel tcpChannel = new TcpChannel();
            ChannelServices.RegisterChannel(tcpChannel,true);
            Type requiredType = typeof(IFooMgr);
            IFooMgr remoteObject = (IFooMgr)Activator.GetObject(requiredType,
                "tcp://localhost:1237/FooManager");
            IList<IFoo> foos = remoteObject.GetList();
            foreach (IFoo foo in foos)
            {
                 Console.WriteLine("IsProxy:{0}, Name:{1}",
                      RemotingServices.IsTransparentProxy(foo), foo.Name);
            }
            Console.ReadLine();
        }
    }
}

, , , foo , , ​​ .


: , IFoo, :

[Serializable]
public class Foo2 : IFoo
{
    public string Name { get; set; }
}

, , , Surrogate , MBR .

+1

IFoos (Foo, ), Foo. MarshalByRefObject -, . .

, Foo [Serializable] ISerializable. .

, , , , . - , Foo GAC .

0

Remoting: Foo MarshalByRefObject Remoting, Remoting. FooManager, Foo. , , , .

: GetAllFooIds(), / Foo, GetFoo, Foo.

Update I think that perhaps my presentation was not clear enough. The fact is that the object is either serialized or MarshalByRefObject. In your case, List <> is serializable and, as such, cannot contain an instance of the MarshalByRefObject. As I suggested, I break the calls: one to get the identifiers, and the other to get a separate item. Slowly, yes, but this is the only way I can do this.

0
source

Source: https://habr.com/ru/post/1761120/


All Articles