I understood that anonymous types are marked private by the compiler and the properties are read-only. Is there a way to serialize them to xml (without deserialize) ? It works with JSON, how can I do it with XML?
+2
A:
Sorry, you cannot. The XML Serializer pretty much just serializes public read-write types.
John Saunders
2010-03-08 21:02:26
That doesn't mean you can't do it with a third-party class, though.
Matthew Flaschen
2010-03-08 21:23:50
is it possible to write something generic?
Radu
2010-03-08 21:32:13
@Radu: I don't know what you mean "write something generic". Not if you're talking about using the XML Serializer. The answer from "Matthew Whited" shows you how to do this without using the XML Serializer.
John Saunders
2010-03-08 21:50:51
@Downvoter: you would have a much greater impact if you gave your reasons for downvoting. I always do, and it really helps the answerer understand what he did wrong, and they often correct their problem. It's not possible to correct the problem you saw, because you haven't told us what the problem is.
John Saunders
2010-03-09 04:31:35
It's probably one of the guys that downvotes all answers that don't get marked as the "correct" answer. Shame that people can't see that you are also correct in that the built-in xml serializer will not work.
Matthew Whited
2010-03-09 04:38:56
+6
A:
Something like this should get you started...
class Program
{
static void Main(string[] args)
{
var me = new
{
Hello = "World",
Other = new
{
My = "Object",
V = 1,
B = (byte)2
}
};
var x = me.ToXml();
}
}
public static class Tools
{
private static readonly Type[] WriteTypes = new[] {
typeof(string), typeof(DateTime), typeof(Enum),
typeof(decimal), typeof(Guid),
};
public static bool IsSimpleType(this Type type)
{
return type.IsPrimitive || WriteTypes.Contains(type);
}
public static XElement ToXml(this object input)
{
return input.ToXml(null);
}
public static XElement ToXml(this object input, string element)
{
if (input == null)
return null;
if (string.IsNullOrEmpty(element))
element = "object";
element = XmlConvert.EncodeName(element);
var ret = new XElement(element);
if (input != null)
{
var type = input.GetType();
var props = type.GetProperties();
var elements = from prop in props
let name = XmlConvert.EncodeName(prop.Name)
let val = prop.GetValue(input, null)
let value = prop.PropertyType.IsSimpleType()
? new XElement(name, val)
: val.ToXml(name)
where value != null
select value;
ret.Add(elements);
}
return ret;
}
}
... resulting xml ...
<object>
<Hello>World</Hello>
<Other>
<My>Object</My>
<V>1</V>
<B>2</B>
</Other>
</object>
Matthew Whited
2010-03-08 21:43:24
I guess `Type.IsValueType` could be a nice shortcut for most of the `IsAssignableFrom` s. Doesn't catch the `string` though.
Markus
2010-08-16 15:55:13
`IsValueType` can be a wrong choice. This would use the ToString value to convert the type. But I have made a change that should be much easier to understand.
Matthew Whited
2010-08-16 17:26:24