In Web API, I have created a custom MediaTypeFormatter to create JSON output with a specific schema, making standard serialization unsuitable. Not that the context above may be relevant, but I need to convert an object, and also IEnumerable to JSON with a schema I specify.
In pseudo code:
If object is a collection
foreach item in collection
Write the name/type of the item (will be same for all)
foreach property of item
Write the property name, type, and value
Else
foreach property of object
Write the property name, type, and value
The part I am most interested in is acquiring a class property name/value via reflection.
For example, this sent from a controller:
return new MyPerson { .FirstName = "Bob", .DateOfBirth = Convert.ToDateTime("1979-03-01") }
...would be outputted as (crude example as the JSON is easy to change to craft the necessary schema):
{ "MyPerson" : {"FirstName": {"value": "Bob", "Type": "string"}}, "DateOfBirth": {"value": "1979-03-01", "Type": "date"}}
Likewise, a collection would be iterated to produce a similar output:
return new IEnumerable<Foo>() {
new Foo() { Param1 = "aaa", Param2 = "bbb" },
new Foo() { Param1 = "ccc", Param2 = "ddd" }
}
...producing
{ "FooCollection": [
{ "Foo" : {"Param1": {"value": "aaa", "Type": "string"}}, {"Param2": {"value": "bbb", "Type": "string"}} },
{ "Foo" : {"Param1": {"value": "ccc", "Type": "string"}}, {"Param2": {"value": "ddd", "Type": "string"}} }
]}
I have tried to digest many other examples (1,2) relating to this challenge, but am struggling to adapt them. This is as far as I've managed to get:
private void WriteStream(Type type, object value, Stream stream, HttpContentHeaders contentHeaders)
{
using (StringWriter _stringWriter = new StringWriter()) {
if (!(value is ICollection))
{
foreach (PropertyInfo p in value.GetProperties())
{
_stringWriter.Write(GetPropertyData(p));
}
}
else
{
foreach (object o in value)
{
foreach (PropertyInfo p in o.GetProperties())
{
_stringWriter.Write(GetPropertyData(p));
}
}
}
// output omitted for brevity...
}
}
public function GetPropertyData(PropertyInfo p) {
return string.Format("{name: '{0}', type: '{1}', value: '{2}'},",
p.Name,
p.PropertyType.ToString(),
p.GetValue(p).ToString())
}