views:

280

answers:

4

I can map incoming class names by using a SerializationBinder and overriding the BindToType method, but I found no way of changing the name of the class in the serialization process. Is it possible at all??

EDIT:

I am referring to the serialization using the System.Runtime.Serialization, and not the System.Xml.Serialization.

Thanks!

A: 

I'm not sure if I follow you, but you could use XmlTypeAttribute. You can then easily retrieve its values through reflection.

[XmlType(Namespace = "myNamespaceThatWontChange",
TypeName = "myClassThatWontChange")]
public class Person
{
   public string Name;
}

Check this out:

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmltypeattribute%28VS.100%29.aspx

Pedro
But this is XmlSerialization, I am talking about the serialization that uses the SerializableAttribute and ISerializable interface.
Miguel Angelo
Islam Ibrahim's answer is 'the' answer then (as far as I know).
Pedro
A: 

You can do it with attributes:

[System.Xml.Serialization.XmlRoot("xmlName")]
public Class ClassName
{
}
Serhat Özgel
+1  A: 

Look at using a surrogate + surrogate selector. That together with a binder on the deserialization should do the trick.

MaLio
This is very interesting, but it is not what I was looking for. I found out that I can use the `SerializationInfo` object of the `GetObjectData` and change both `AssemblyName` and `FullTypeName` properties.
Miguel Angelo
This is rather dangerous in the way that you may need to serialize instances indifferent contexts. i.e. data transfer between tiers, cloning, peristance etc. If you do go this route, be sure to specify the streaming context. (example)formatter.Context = new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.CrossMachine); and be aware also that you will be tied to the binder that you name the items for.
MaLio
A: 

I found out that I can use the SerializationInfo object that comes in the GetObjectData function, and change the AssemblyName and FullTypeName properties, so that when I deserialize I can use a SerializationBinder to map the custom assembly and type-name back to a valid type. Here is a semple:

Serializable class:

[Serializable]
class MyCustomClass : ISerializable
{
    string _field;
    void MyCustomClass(SerializationInfo info, StreamingContext context)
    {
        this._field = info.GetString("PropertyName");
    }
    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AssemblyName = "MyCustomAssemblyIdentifier";
        info.FullTypeName = "MyCustomTypeIdentifier";
        info.AddValue("PropertyName", this._field);
    }
}

SerializationBinder:

public class MyBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        if (assemblyName == "MyCustomAssemblyIdentifier")
            if (typeName == "MyCustomTypeIdentifier")
                return typeof();
        return null;
    }
}

Serialization code:

var fs = GetStream();
BinaryFormatter f = new BinaryFormatter();
f.Binder = new MyBinder();
var obj = (MyCustomClass)f.Deserialize(fs);

Deserialization code:

var fs = GetStream();
MyCustomClass obj = GetObjectToSerialize();
BinaryFormatter f = new BinaryFormatter();
f.Deserialize(fs, obj);
Miguel Angelo