Click here to Skip to main content
15,883,705 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));
    }


}
 
Share this answer
 

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