3

I am trying to return an IEnumerable from my ASP.NET Web Api controller .. I have the following in my ApiController ...

        public IEnumerable<dynamic> Get()
        {
            var personRepository = new PersonRepository();
            var parameters = HttpUtility.ParseQueryString(Request.RequestUri.Query);

            return personRepository.GetAll(parameters)
                .Select(x => new
                {
                    Name = x.Name
                });
        }

When I execute my code I receive the following error ...

<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type '<>f__AnonymousType3`1[System.String]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.
</ExceptionMessage>
<ExceptionType>
System.Runtime.Serialization.InvalidDataContractException
</ExceptionType>
<StackTrace>
at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type) at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id, RuntimeTypeHandle typeHandle, Type type) at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(Int32 id, RuntimeTypeHandle typeHandle, Type type) at System.Runtime.Serialization.XmlObjectSerializerContext.GetDataContract(RuntimeTypeHandle typeHandle, Type type) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at WriteArrayOfanyTypeToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract ) at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) at System.Net.Http.Formatting.XmlMediaTypeFormatter.<>c__DisplayClass7.<WriteToStreamAsync>b__6() at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)
</StackTrace>
</InnerException>
</Error>

Is what I am wanting/trying to do possible?

Update

If I execute my request through Fiddler, then it works, as it is returning JSON. So it looks like it is just an XML serialization issue, which I don't need to support XML. Just bums me out that it throws an error if you try to call it via a web browser uri.

I found this https://stackoverflow.com/a/12629311/1768, and forced all my returns to be JSON.

Community
  • 1
  • 1
mattruma
  • 16,589
  • 32
  • 107
  • 171

2 Answers2

2

I would suggest you return IEnumerable<object> or JArray or IEnumerable<JObject> instead.

Ben Reich
  • 16,222
  • 2
  • 38
  • 59
Thai Anh Duc
  • 524
  • 6
  • 12
  • 1
    Switching it to IEnumerable does not work ... can you show me how you would do it? – mattruma May 17 '13 at 12:21
  • I have not done with IEnumerable but i have done many with JArray and IEnumerable. You can get those object from Json.net (from here http://james.newtonking.com/pages/json-net.aspx). I always prefer using JSON in WebApi. – Thai Anh Duc May 17 '13 at 14:41
2

The built in XML serializers will not serialize dynamic. You will need to use an alternative serialization method. i.e. different formatters.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243