consider the following class and struct
public class Entity {
public IdType Id {get;set;}
public string Data {get;set;}
}
[TypeConverter(IdTypeConverter))]
public struct IdType {
... any data ...
}
The IdTypeConverter can convert the IdType struct from and to string.
Now, what I want is this class to be serializable for AJAX, WCF and ViewState. The senario could be a WCF web service which provides as array of Entity[] to a DataSource. And a custom control which binds to the datasource, saves this class to it’s ViewState and sends the data to client side code.
This could be achieved easily by simply adding a [Serializable] attribute to all serialized types. But I don’t want the IdType to be serialized, but to be converted to a string. Thus the JSON representation should be
{ 'Id'=>'StringRepresentationOfId', 'Data'=>'foo' }
This would analogously be the optimal serialization for WCF and ViewState.
Another solution would be to write another class
public class JsonEntity {
public JsonEntity(Entity from) {
Id = from.Id;
Data = from.Data;
}
public string Id {get;set;}
public string Data {get;set;}
}
and use this for JsonSerialization. But I don’t like this, because this would imply that the control which is sending the data to the client knows about the Entity type.
The actual question is: Is it possible to customize JsonSerialization with attributes without breaking WCF and ViewState serialization?
EDIT:
An answer like “That’ impossible” would satify me, since I’d stop trying.
From what I’ve read, the LosFormatter class used for ViewState serialization checks if there is a TypeConverter for a given object and uses it, so you should be covered there.
This article describes how to create your own JavaScriptConverter to perform custom serialization. The Serialize method that you have to implement returns
IDictionary<string, object>, so you might have to create a JavaScriptConverter class for your Entity class rather than for your IdType struct. Below is an example, though I haven’t had a chance to test it out:Note: the examples in my post just look up the associated TypeConverter for IdType in order to convert it to a string, but unless there’s a specific reason to do it that way you might as well just call a specific function (e.g. override ToString) that returns a the string representation directly instead of looking up the TypeConverter as my example code is doing.
If you also want the behavior that you described for XML serialization, you could have the IdType struct implement the IXmlSerializable interface. Below is an example of a WriteXml method implementation that uses the TypeConverter defined for the IdType struct: