views:

28

answers:

2

In MVC I can do something like the following to serialise an object with an anonymous type to JSON...

    Public Function GetStateList() As JsonResult
        Dim MyObject = New With {.Id = 1, .Property = "SomeValue"}
        Return Me.Json(MyObject)
    End Function

which would return something like;

{
    "Id": 1,
    "Property"SomeValue",
}

I'd like to do exactly the same but output xml. I haven't been able to find an equivalent method. Would someone please point me in the right direction?

Many thanks

+1  A: 

The short answer is you cannot, see this post. I recommend you create a concrete type to represent the structure of your anonymous output, and then use a normal XML serialization technique like the example I've provided below.

Here is basic example of how to use this (sorry it's in C# syntax):

using (MemoryStream memStream = new MemoryStream())
{
    System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding(); 
    // read and convert to byte array
    XmlSerializer serializer = new XmlSerializer( <<yourObject>>.GetType() ); 
    serializer.Serialize( memStream, <<yourObject>>)); 
    string output = utf8.GetString( memStream.ToArray() );
}
James
A: 

As per James' answer there is no native way of doing this. Using Reflector, I examined the System.Web.MVC.dll and and found out how MVC does it. The core of the code is below.

Private Sub SerializeCustomObject(ByVal o As Object, ByVal sb As StringBuilder, ByVal depth As Integer, ByVal objectsInUse As Hashtable, ByVal serializationFormat As SerializationFormat)
    Dim flag As Boolean = True
    Dim type As Type = o.GetType
    sb.Append("{"c)
    If (Not Me.TypeResolver Is Nothing) Then
        Dim str As String = Me.TypeResolver.ResolveTypeId(type)
        If (Not str Is Nothing) Then
            JavaScriptSerializer.SerializeString("__type", sb)
            sb.Append(":"c)
            Me.SerializeValue(str, sb, depth, objectsInUse, serializationFormat)
            flag = False
        End If
    End If
    Dim info As FieldInfo
    For Each info In type.GetFields((BindingFlags.Public Or BindingFlags.Instance))
        If Not info.IsDefined(GetType(ScriptIgnoreAttribute), True) Then
            If Not flag Then
                sb.Append(","c)
            End If
            JavaScriptSerializer.SerializeString(info.Name, sb)
            sb.Append(":"c)
            Me.SerializeValue(info.GetValue(o), sb, depth, objectsInUse, serializationFormat)
            flag = False
        End If
    Next
    Dim info2 As PropertyInfo
    For Each info2 In type.GetProperties((BindingFlags.GetProperty Or (BindingFlags.Public Or BindingFlags.Instance)))
        If Not info2.IsDefined(GetType(ScriptIgnoreAttribute), True) Then
            Dim getMethod As MethodInfo = info2.GetGetMethod
            If ((Not getMethod Is Nothing) AndAlso (getMethod.GetParameters.Length <= 0)) Then
                If Not flag Then
                    sb.Append(","c)
                End If
                JavaScriptSerializer.SerializeString(info2.Name, sb)
                sb.Append(":"c)
                Me.SerializeValue(getMethod.Invoke(o, Nothing), sb, depth, objectsInUse, serializationFormat)
                flag = False
            End If
        End If
    Next
    sb.Append("}"c)
End Sub
Basiclife