List<dynamic> in API

Topics: Web Api
Oct 12, 2011 at 11:10 AM


For some business reasons, I need to have a List<dynamic> as a member in my entity that will be returned via API.

For example,

public class Contact
        public string Name { get; set; }
        public int Id { get; set; }
        public List<dynamic> list { get ; set; }

This list could be of any of following 2 types/classes depending upon business logic.

public class List1
        public string List1Field1 { get; set; }

    public class List2
        public string List2Field1 { get; set; }
        public int List2Field2 { get; set; }

I initialize my collection as -

private static List<Contact> contacts = new List<Contact>()
            new Contact { Name = "First Contact", Id = totalContacts++, list= new List<dynamic> { new List1 { List1Field1="l1f1"} } },
            new Contact { Name = "Second Contact", Id = totalContacts++, list= new List<dynamic> { new List2 { List2Field1="l2f1",List2Field2=99}} },
            new Contact { Name = "Third Contact", Id = totalContacts++ , list= new List<dynamic> { new List1 { List1Field1="l1f1"} }},
            new Contact { Name = "Fourth Contact", Id = totalContacts++ , list= new List<dynamic> { new List1 { List1Field1="l1f1"} }},

and then return via GET as below

 [WebGet(UriTemplate = "")]
        public List<Contact> Get()
            return contacts.AsQueryable();

But I get this error "ReadResponse() failed: The server did not return a response for this request.".

What's problem?How to solve?


Oct 12, 2011 at 2:38 PM

Would it be possible for you to use “object” instead of “dynamic” when generating the result. That is, you can use dynamic internally but build a new type for serialization?


Oct 12, 2011 at 4:42 PM

Our formatters don't support dynamic out of the box. Here are few options you could consider.

1. Use object rather than dynamic as our serializer should be able to support that.

2. Return a different type for serialization. One pattern to use here is to have an extension method like ToContactResponse<T> which takes in a contact or collection of contact and then transforms it into a new type which can be serialized.

3. Create a custom formatter that can support writing dynamic.


Oct 13, 2011 at 7:36 AM


Thanks for suggestions. But..

1. Replacing object with dymanic doesn't work.

2. Creating extension method implies that new type has to have a "uniform" shape. That's precisely the problem as the list inside contact is of "irregular" shape.

3. Custom formatter. Can you point me to any specific information? Wouldn't same issue pop up in custom formatter too?


Oct 13, 2011 at 12:54 PM

Assuming you are trying to output some form of XML, you could implement IXMLSerializable on your List1 and List2 objects and control exactly how they are going to get serialized out.  I must admit that I have never tried using the XmlSerializer to serialize a List<IXMLSerializable> but it might work.  If it doesn't then you can always create your own collection class that itself implements IXmlSerializable.  

Oct 20, 2011 at 6:10 PM

I had the same issue, for different reasons, mainly I want to use dynamic linq to return a list of objects. I wrote the following as my media formatter.


public class XmlProcessor : XmlMediaTypeFormatter
	private static readonly LogWrapper Logger = new LogWrapper();

	public XmlProcessor()
		SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
		SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));

	private string ToJson(object value)
		return JsonConvert.SerializeObject(value, JsonFormatting.None, JsonNetProcessor.DefaultJsonSerializerSettings);
	protected override void OnWriteToStream(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, System.Net.TransportContext context)

		var json = string.Format("{{{0}root{0}:{1}}}", '"', ToJson(value));
		var doc = JsonConvert.DeserializeXmlNode(json);
		using (var sw = new StreamWriter(stream))


Then in my global.asax.cs file in RegisterRoutes(), this is more than the things you are doing, but the main point is the hostConfig.Formatters.Insert(1, new XmlPRocessor());


var hostConfig = new HttpConfiguration
					EnableHelpPage = true,
					EnableTestClient = true,
					IncludeExceptionDetail = true,
					MessageHandlerFactory = () => new System.Net.Http.DelegatingHandler[] { new FormattingHandler() },
					ErrorHandlers = (handlers, endpoint, descriptions) => handlers.Add(new ErrorHandler()),
					ResponseHandlers = (handlers, endpoint, operation) => handlers.Add(new ResponseHandler())
hostConfig.Formatters.Insert(0, new JsonNetProcessor());
hostConfig.Formatters.Insert(1, new XmlProcessor());

RouteTable.Routes.Add(new ServiceRoute("$meta", new HttpServiceHostFactory { Configuration = hostConfig }, typeof(API.Global)));