Click here to Skip to main content
14,869,895 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
This should be possible however I have searched extensively and have found no answers to this, using WCF ISerializable interface concept. Hopefully the experts can help.

Any documentation I have read only refers to info.AddValue(...) concept similar to the ones in https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.iserializable?view=netframework-4.8

In summary I have a SW which does operations like Image processing in a single EXE. I would like to use WCF Service/Client approach and do this processing on separate services on same PC or different PC's. Well basically distribute the process.

I have a WCF service with endpoints, connects & communicates to the services etc, all good here.

I want to send the entire object of a class(with its local variables/objects), which has been created on the client, across to the service.

I have the class derived from the ISerializable interface. Class attribute is [Serializable]. It has the required constructor & GetObjectData() public Foo(SerializationInfo info, StreamingContext context) public void GetObjectData(SerializationInfo info, StreamingContext context)

This object is Serialized using the BinaryFormatter to a byte[] and sent. On the service side it is Deserialized to the class object.

During Serialization it does go into GetObjectData() and does its task. BUT during deserialization the class object I get is just the default object not the object which was sent, local variables/objects are not initialized.

This class object is not a singleton, nor I want to that as there are many instances of this on separate threads. I would think one does not have to do a Addvalue on every parameter of a class. As this is just one class I referring to, eventually I have to send many such class objects.

I have tried using a helper class with IObjectReference interface concept using the GetRealObject() --> BUT how do I get the original object from this?

I have read about Surrogates, again no good exaple on how to send the entire object of a class.

I want the entire object of this class on the Service side.

The classes I want to send are much bigger and complex than 2 Int's, it has objects of other classes, dictionaries etc. point is how to get the Object of this class, it seems like it is in the SerializationInfo object BUT cannot find a way to get it out

Hope I am clear on my question. I am new to the WCF conecpts, I am probably missing some secret to make this work.

Please suggest any ideas!

What I have tried:

Example Code, this is the basic version of what I want to do.

I need cls2 object which has Add() performed already thus num1 & num2 are updated, to be received on the service side with the right values of Add() like 100 & 200. ImgProcessingConnector() is handling all the stuff for connecting to the Service.

WCF Client

C#
public Form1()
    {
        InitializeComponent();
        cls2 = new Class2();            
    }

    private void button1_Click(object sender, EventArgs e)
    {
        byte[] cls2Byted = Class1.SerializedtoByte(cls2);

        ImgProcessingConnector.Instance().PerformAction(cls2Byted);
    }

    Class2 cls2 = null;


WCF Service

C#
public class ImageProcessingWCFService : IImageProcessingWCFService
{
    public ImageProcessingWCFService()
    {

    }

    public bool PerformAction(byte[] cls2Byted)
    {
        Class2 cls2 = Class1.DeSerializedfromByte(cls2Byted) as Class2;

        cls2.Subtract();

        return true;
    }
}

Class2

C#
[Serializable]
public class Class2 : ISerializable
{
    public Class2()
    {
        Add();
    }

    public Class2(SerializationInfo info, StreamingContext context)
    {

    }

    public void Add()
    {
        num1 = 50 + 50;
        num2 = 100 + 100;
    }

    public void Subtract()
    {
        num1 = 50 - 50;
        num2 = 100 - 100;
    }

    int num1;
    int num2;

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        //nothing to do send ALL.
    }
}
Posted
Updated 1-Dec-19 9:17am
Comments
johannesnestler 4-Dec-19 6:55am
   
just use WCF default's datacontract serializer (just do nothing special on your DTO-Class) - so everything should behave naturally. Why did you come up with (the old) Serializable idea…

1 solution

Seems, you don't understand what Serialization[^] is...

An object to serialize/deserialize have to have at least one public member. But Class2 has got none public member!
See: ISerializable Interface (System.Runtime.Serialization) | Microsoft Docs[^]

C#
void Main()
{
	Class2 t = new Class2();
	t.num1 = 50;
	t.num2 = 100;
	Console.WriteLine("Initial values of class2: num1={0} | num2={1}", t.num1, t.num2);
	t.num2 = t.Add();
	Console.WriteLine("After using Add() method: num1={0} | num2={1}", t.num1, t.num2);

	string sFile = @"D:\tmp.data";
	IFormatter formatter = new BinaryFormatter();
	bool retVal = SerializeClass(sFile, formatter, t);
	if(retVal)
	{
		Console.WriteLine("Class2 has been sucesfully serialized!");
		t = DeserializeClass(sFile, formatter);
		if(t!=null)
		{
			Console.WriteLine("Class2 has been sucesfully deserialized!");
			Console.WriteLine("num1={0} | num2={1}", t.num1, t.num2);
			t.num2 = t.Subtract();
			Console.WriteLine("After Subtract() method: num1={0} | num2={1}", t.num1, t.num2);
		}
	}
}

//methods used in Main:
public bool SerializeClass(string fileName, IFormatter formatter, Class2 c)
{
	bool retVal = true;
    try
	{
		FileStream s = new FileStream(fileName , FileMode.Create);
	    formatter.Serialize(s, c);
		s.Close();
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.Message);
		retVal = false;
	}
	
	return retVal;
}


public Class2 DeserializeClass(string fileName, IFormatter formatter)
{
	Class2 c = new Class2();
    try
	{
    FileStream s = new FileStream(fileName, FileMode.Open);
    c = (Class2)formatter.Deserialize(s);
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.Message);
	}
	return c;
} 

// Class2 definition
[Serializable]
public class Class2 : ISerializable
{

    public int num1 = 0;
    public int num2 = 0;
	
	public Class2()
    {
        //empty constructor is required to compile
    }

    public int Add()
    {
        return num1 + num2;
    }

    public int Subtract()
    {
        return num2 - num1;
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("num1", num1, typeof(int));
		info.AddValue("num2", num2, typeof(int));
    }
	
	public Class2(SerializationInfo info, StreamingContext context)
    {
        // Reset the property value using the GetValue method.
        num1 = (int)info.GetValue("num1", typeof(int));
		num2 = (int)info.GetValue("num2", typeof(int));
    }


}
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900