nicolas
nicolas

Reputation: 7668

WebAPI List<T> Serialization XML/JSON output

I tried to create a method in a ApiController that looks like this:

public DemoList<Demo> GetAll()
{
    var result = new DemoList<Demo>() { new Demo(){Y=2}, new Demo(), new Demo(){Y=1} };
    result.Name = "Test";
    return result;
}

Demo and DemoList look like this:

public interface INamedEnumerable<out T> : IEnumerable<T>
{
    string Name { get; set; }
}

public class Demo
{
    public int X { get { return 3; } }
    public int Y { get; set; }
}

public class DemoList<T> : List<T>, INamedEnumerable<T>
{
    public DemoList()
    {
    }

    public string Name { get; set; } 
}

I then cheked the ouput with fiddler

GET http://localhost:8086/api/Demo

and got the following:

XML (Accept header set to application/xml)

<ArrayOfDemo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/XXX.WebAPI"><Demo><Y>2</Y></Demo><Demo><Y>0</Y></Demo><Demo><Y>1</Y></Demo></ArrayOfDemo>

JSON (Accept header set to application/json)

[{"X":3,"Y":2},{"X":3,"Y":0},{"X":3,"Y":1}]

My question is quite simple: Why is the X variable not serialized with the XML version (I thought that readonly properties were serialized) and more important, why in both cases is the Name property (which is writable) not serialized?? What are the alternatives to make this work like I expected?

Edit: Please, note that I'm in a WebAPI context! By default, the XmlSerializer is automatically set to XmlMediaTypeFormatter and the JSONSerializer to JsonMediaTypeFormatter

Upvotes: 0

Views: 2518

Answers (3)

nicolas
nicolas

Reputation: 7668

This seems to be a bug... using the following workaround made the trick:

public class ListWrapper<T>
{
    public ListWrapper(INamedEnumerable<T> list)
    {
        List = new List<T>(list);
        Name = list.Name;
    }

    public List<T> List { get; set; }

    public string Name { get; set; }
}

Upvotes: 1

ramsey_tm
ramsey_tm

Reputation: 792

What are you using to serialize it? If you don't need attributes you could use DataContractSerializer as mentioned here. By default properties without a set are not serialized however using DataContractSerializer or implementing IXmlSerializable should do the trick for you.

using System;
using System.Runtime.Serialization;
using System.Xml;
[DataContract]
class MyObject {
    public MyObject(Guid id) { this.id = id; }
    [DataMember(Name="Id")]
    private Guid id;
    public Guid Id { get {return id;}}
}
static class Program {
    static void Main() {
        var ser = new DataContractSerializer(typeof(MyObject));
        var obj = new MyObject(Guid.NewGuid());
        using(XmlWriter xw = XmlWriter.Create(Console.Out)) {
            ser.WriteObject(xw, obj);
        }
    }
}

Upvotes: 0

Krzysiek Bronek
Krzysiek Bronek

Reputation: 146

XML serializers only allows serialization of properties with "set" provided.

Upvotes: 0

Related Questions