Starter question: remoting

Posts   
 
    
Dominique
User
Posts: 22
Joined: 13-Sep-2005
# Posted on: 23-Nov-2006 10:05:24   

Hello,

I'm trying to use remoting under IIS for the first time to send a collection from the server to the client, but I'm doing something wrong I guess. For testing I'm trying to do it with selfservicing, I know I shoud do it with adapter.

This is the service code:

public MemoryStream Getcustomerlist()
        {
            Sean.Dal.HelperClasses.DbUtils.ActualConnectionString = @"Database=C:\Temp\POLISAGENT.FDB;DataSource=127.0.0.1;User=SYSDBA;Password=masterkey; Port=3050;Role=;CharSet=ISO8859_1";
            Sean.Dal.CollectionClasses.AgentenCollection agenten = new AgentenCollection();
            agenten.GetMulti(null);
            BinaryFormatter b = new BinaryFormatter(); // create the formatter
            MemoryStream s = new MemoryStream();
            b.Serialize(s, agenten);
            return s;
        }

This is the client code:

private void simpleButton1_Click(object sender, EventArgs e)
        {
            string CLIENT_URL = "http://localhost/IISRemotingHosting/Customer.rem";
            RemotingConfiguration.RegisterWellKnownClientType(typeof(Customer), CLIENT_URL);
            Sean.Dal.CollectionClasses.AgentenCollection agentenlist = new AgentenCollection();
            AcBusinessObjects.Customer cust = new Customer();
            //Sean.Dal.CollectionClasses.AgentenCollection agenten;
            MemoryStream agenten = cust.Getcustomerlist();
            BinaryFormatter b = new BinaryFormatter(); 
            agentenlist = (AgentenCollection)b.Deserialize(agenten);    
        }

When I'm running this, I get the following error: End of Stream encountered before parsing was completed.

When I try without the binaryformatter I get: Soap Serializer does not support serializing Generic Types : System.Collections.Generic.Dictionary2[System.Guid,System.Collections.Generic.Dictionary2[ System.String,SD.LLBLGen.Pro.ORMSupportClasses.EntitySyncInfo`1[SD.LLBLGen.Pro.ORMSupportClasses.IEntity]]].

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 23-Nov-2006 11:30:18   

soap formatter doesnt' support generics, so you can safely ignore that one. Microsoft doesn't update the soap formatter anymore.

The binary formatter should work OK. You get an error that the stream was broken. What I don't understand is why you return a memory stream. You can't do that, you should return the collection itself.

Frans Bouma | Lead developer LLBLGen Pro
Dominique
User
Posts: 22
Joined: 13-Sep-2005
# Posted on: 23-Nov-2006 11:59:11   

How would I do this in code? Sorry probably a stupid question.

Dopminique.

jbb avatar
jbb
User
Posts: 267
Joined: 29-Nov-2005
# Posted on: 23-Nov-2006 14:37:18   

Hello,

if you want to serialize, I think it's better to use a byte's array like this :

public byte[] Getcustomerlist()
        {
            Sean.Dal.HelperClasses.DbUtils.ActualConnectionString = @"Database=C:\Temp\POLISAGENT.FDB;DataSource=127.0.0.1;User=SYSDBA;Password=masterkey; Port=3050;Role=;CharSet=ISO8859_1";
            Sean.Dal.CollectionClasses.AgentenCollection agenten = new AgentenCollection();
            agenten.GetMulti(null);
            BinaryFormatter b = new BinaryFormatter(); // create the formatter
            MemoryStream s = new MemoryStream();
            b.Serialize(s, agenten);
           return s.ToArray();
        }

And on client side, get the byte's array inside of the memory stream :

private void simpleButton1_Click(object sender, EventArgs e)
        {
            string CLIENT_URL = "http://localhost/IISRemotingHosting/Customer.rem";
            RemotingConfiguration.RegisterWellKnownClientType(typeof(Customer), CLIENT_URL);
            Sean.Dal.CollectionClasses.AgentenCollection agentenlist = new AgentenCollection();
            AcBusinessObjects.Customer cust = new Customer();
            //Sean.Dal.CollectionClasses.AgentenCollection agenten;
            MemoryStream agenten = new MemoryStream(cust.Getcustomerlist());
            BinaryFormatter b = new BinaryFormatter(); 
            agentenlist = (AgentenCollection)b.Deserialize(agenten);    
        }

Dominique
User
Posts: 22
Joined: 13-Sep-2005
# Posted on: 23-Nov-2006 15:26:26   

Thx, works great. Now my last question smile I've got a form with an agentcollection object on my form (auto generated from my dal) and a bindingsource and a grid. I've connected the agentcollection to the bindingsource and the grid also to the bindingsource. Now I would like to put the received data in the agentcollection object on my form, so I do this: agentenCollection1 = (AgentenCollection)b.Deserialize(agenten); But this does not display the data. If I bind the grid directly to the collection created in code, it works.

Dominique.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 24-Nov-2006 10:27:42   

Still, I'd use this

public Sean.Dal.CollectionClasses.AgentenCollection Getcustomerlist()
        {
            Sean.Dal.HelperClasses.DbUtils.ActualConnectionString = @"Database=C:\Temp\POLISAGENT.FDB;DataSource=127.0.0.1;User=SYSDBA;Password=masterkey; Port=3050;Role=;CharSet=ISO8859_1";
            Sean.Dal.CollectionClasses.AgentenCollection agenten = new AgentenCollection();
            agenten.GetMulti(null);
            return agenten;
        }

then on the client simply retrieve the AgentenCollection from the service and set the bindingsource.DataSource to it. The data then should show up in the form.

Frans Bouma | Lead developer LLBLGen Pro
Dominique
User
Posts: 22
Joined: 13-Sep-2005
# Posted on: 24-Nov-2006 11:37:49   

I tried that, but I get the following error:

Soap Serializer does not support serializing Generic Types : System.Collections.Generic.Dictionary2[System.Guid,System.Collections.Generic.Dictionary2[ System.String,SD.LLBLGen.Pro.ORMSupportClasses.EntitySyncInfo`1[SD.LLBLGen.Pro.ORMSupportClasses.IEntity]]].

Dominique.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 24-Nov-2006 12:26:53   

You of course should use the binary formatter in that case.

Frans Bouma | Lead developer LLBLGen Pro
Dominique
User
Posts: 22
Joined: 13-Sep-2005
# Posted on: 24-Nov-2006 13:03:15   

Are there no samples available using llblgen and remoting? I'm new to remoting and I don't know how to use the binary formatter. I've been messing around almost a day now.

Dominique.

Aurelien avatar
Aurelien
Support Team
Posts: 162
Joined: 28-Jun-2006
# Posted on: 24-Nov-2006 14:43:34   

Hi, You can use a BinaryFormatter like that :


BinaryFormatter bf=new BinaryFormatter();
bf.Serialize(s,obj);

where s is a Stream and obj yhe object you want to serialize.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 24-Nov-2006 15:29:54   

Aurelien: he wants to know how to make the SERVICE use the binary formatter wink

So this should be configured in the config file of the service. Dominique: you should check the MSDN documentation about this: please check Remoting -> Configuration in the MSDN documentation of vs.net to learn more about how to specify formatters for a remoting channel and thus how to specify that you want to use the binary formatter.

Frans Bouma | Lead developer LLBLGen Pro
sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 24-Nov-2006 16:00:19   

You need to define the remoted types at server in web.config like this:



    <system.runtime.remoting>
        <application>
            <channels>
                <channel ref="http">
                    <serverProviders>
                        <provider ref="wsdl"/>                      
                        <formatter ref="binary" typeFilterLevel="Full"/>
                    </serverProviders>
                    <clientProviders>
                        <formatter ref="binary"/>
                    </clientProviders>
                </channel>
            </channels>
            <service>
                <wellknown mode="SingleCall" objectUri="SomeService.rem" type="MyCompany.Application.SomeService, MyAssembly.SomeService"/>
            </service>
        </application>
    </system.runtime.remoting>


And you need to configure those at client too, at app.config or manually in the code.



<system.runtime.remoting>
    <application>
      <client>      
          <wellknown type="MyCompany.Application.Shared.ISomeService, MyCompany.Application.Shared" url="http://192.168.1.66:80/server/SomeService.rem" />
      </client>
    </application>
  </system.runtime.remoting>


Just to get on the road. Like Otis mentioned there is a good documentation in MSDN.

Extremely nice stuff from Ingo Rammer, which I found very usefull:

http://www.thinktecture.com/Resources/RemotingFAQ/default.html

Especially this one:

http://www.thinktecture.com/Resources/RemotingFAQ/USEINTERFACESWITHCONFIGFILES.html