I have a class that when serialized, I want to return as a single string without key value pairs. A string becomes a string. An int becomes an int. How do I make my class become a string?
Looking at DataContract and Serializable, it doesn't look that this is possible. The SerializationInfo.AddValue(name, value) setup forces your whole object into a key-value approach. I just want to return "A and B".
[DataContract]
public class MyObject
{
public int A { get; set; }
public int B { get; set; }
}
When serialized using the DataContractJsonSerializer, for example, I want it to be:
4 and 2
Not
{
"A": 4,
"B": 2
}
So let's say I have a parent class that uses both of these custom types:
[DataContract]
public class Parent
{
[DataMember]
public MyObject One { get; set; }
[DataMember]
public MyObject Two { get; set; }
}
I want to it serialize like this:
{
"One": "4 and 2",
"Two": "6 and 8"
}
Instead, the only thing I seem to be able to make it do is:
{
"One": {
"A": 4,
"B": 2
},
"Two": {
"A": 6,
"B": 8
}
}
The only solution that would work, is to add the custom serialization on Parent, setting One and Two accordingly, but I don't want to do that, I want my new class to get serialized as a string everywhere.
Can I serialize a type as a single return value? Or do all types besides built-in ones like int and string have to serialize to an object?
My answer: You can't.
The parent class, MyObject
has to implement ISerializable
to provide the custom serialization of the class itself. This places the responsibility of correctly serializing the class the way it is intended to each class that wishes to use it, which is an undesirable experience, and highlights a severe design flaw in the supported .NET custom serializer strategy.
[Serializable]
public class Parent : ISerializable
{
public MyObject One { get; set; }
public MyObject Two { get; set; }
public (SerializerInfo info, SerializerContext context)
{
string oneString = info.GetString("One");
One = new MyObject(oneString);
string twoString = info.GetString("Two");
Two = new MyObject(twoString);
}
public override void GetObjectData(SerializerInfo info, SerializerContext context)
{
info.AddValue("One", One.ToString());
info.AddValue("Two", Two.ToString());
}
}
Grumble grumble... add this to the long list of things that .NET has gotten wrong. Static / non interfaced classes for everything making the framework untestable by default without creating plug-n-chug wrappers for everything. Compilers with lossful MSIL/symbols. I could go on and on.