WebReference.com - Part 3 of Chapter 6: Professional C# Web Services, from Wrox Press Ltd (3/5)

To page 1To page 2current pageTo page 4To page 5
[previous] [next]

Professional C# Web Services

Marshal-By-Value

To create a class that will be serialized across the network, the class must be marked with the attribute [Serializable]. Objects of these classes don't have a remote identity, as they are marshaled to a stream before they're sent to the channel, and unmarshaled on the other side.

We add class A to the file MyRemoteObject.cs. This class has a field of type int that is also serializable. If a class is marked serializable, but has a reference to a class that is not serializable, the exception SerializationException will be thrown when marshaling this class. The class A defines the read-only property Data where the value of the field data is returned:

[Serializable]
public class A
{
   private int data;
   public A(int data)
   {
      Console.WriteLine("Constructor of serializable class A called");
      this.data = data;
   }
   public int Data
   {
      get
      {
         Console.WriteLine("A.Data called");
         return data;
      }
   }
}

Marshal-By-Reference

A class that should be called remotely is derived from MarshalByRefObject. We have used this class already for our remote object.

We add class B also to MyRemoteObject.cs. This class is similar to class A with the exception that it is not marked serializable; instead it derives from the class MarshalByRefObject. When we pass class B across the network, a proxy will be created.

Behind the scenes, RemotingServices.Marshal() is called to create an ObjRef, this object reference is sent across the channel, and with RemotingServices.Unmarshal() this object reference is used to create a proxy:

public class B : MarshalByRefObject
{
   private int data;
 
   public B(int data)
   {
      Console.WriteLine("Constructor of remotable class B called");
      this.data = data;
   }
   public int Data
   {
      get
      {
         Console.WriteLine("B.Data called");
         return data;
      }
   }
}

Client Example

The server is the same as we have created previously. It is entirely our choice whether we create the channel programmatically or with a configuration file, and whether we use a well-known or a client-activated object.

In the client we can now call the new methods of the remote object class. Let us change the Main() method in the file SimpleClient.cs to call the newly created remote methods:

   static void Main(string[] args)
   {
      RemotingConfiguration.Configure("SimpleClient.exe.config");
      MyRemoteObject obj = new MyRemoteObject();
      obj.Hello();
      A a = obj.GetA();
      int a1 = a.Data;
      B b = obj.GetB();
      int b1 = b.Data;
   }

The remote object class, the server, and the client can be compiled as we saw earlier. When we start the server and the client, we get the console output of the server. B is a remote class, so B.Data is called on the server as we can see here:

Example of server console output

In the client console window we can see the Console.WriteLine() output of the A class because this class was serialized to the client.

Example of client output

Passing objects of classes that are neither marked [Serializable] nor derived from MarshalByRefObject will generate the exception System.Runtime.Serialization. SerializationException: The type typename is not marked as serializable.


To page 1To page 2current pageTo page 4To page 5
[previous] [next]

Created: March 26, 2002
Revised: March 26, 2002


URL: http://webreference.com/programming/csharp/webservices/chap6/3/3.html