Jeppe Koefod Jeppe Koefod - 3 months ago 220
C# Question

Web API - error when returning list of complex objects

I have created a webAPI controller method that looks the following:

[HttpGet]
public HttpResponseMessage RealEstates()
{
using (BoligsideDbContext context = new BoligsideDbContext())
{
List<RealEstateVm> realEstateVms = context.RealEstates.OrderByDescending(x => x.Id).ToList().Select(x => new RealEstateVm(x)).ToList();

return Request.CreateResponse(HttpStatusCode.OK, realEstateVms);
}
}


My VM looks the following:

public class RealEstateVm
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Area { get; set; }
public int Rooms { get; set; }
public int Rent { get; set; }
public string Picture { get; set; }
public RealEstateType Type { get; set; } //this is just an enum
public string Address { get; set; }
public List<string> Images { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Phone2 { get; set; }
public string OriginalUrl { get; set; }
public string OriginalSource { get; set; }
public string City { get; set; }
public int ZipCode { get; set; }
public string StreetAddress { get; set; }
public double Longtitude { get; set; }
public double Latitude { get; set; }
}


However whenever I go to the endpoint I get the following error:


Type 'Boligside.ViewModels.RealEstateVm' 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.


What could be the issue? I don't see why I should have to mark my VM with [DataContractAttribute]?

By the way the complete error message is here:


This XML file does not appear to have any style information associated
with it. The document tree is shown below. An error
has occurred. The 'ObjectContent`1' type
failed to serialize the response body for content type
'application/xml; charset=utf-8'.
System.InvalidOperationException
An error has
occurred. Type
'Boligside.ViewModels.RealEstateVm' 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.

System.Runtime.Serialization.InvalidDataContractException
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(Int32
id, RuntimeTypeHandle typeHandle) at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator
xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType,
Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at
WriteArrayOfRealEstateVmToXml(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.SerializeWithoutXsiType(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj,
RuntimeTypeHandle declaredTypeHandle) 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.WriteToStream(Type
type, Object value, Stream writeStream, HttpContent content) at
System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type
type, Object value, Stream writeStream, HttpContent content,
TransportContext transportContext, CancellationToken
cancellationToken) --- End of stack trace from previous location where
exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at
System.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()


Answer Source

As the error said, It cannot be serialized and consider adding the data contract attribute..

using System.Runtime.Serialization;
[DataContract]
public class RealEstateVm
    {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Title { get; set; }
        [DataMember]
        public string Description { get; set; }
        [DataMember]
        public int Area { get; set; }
        [DataMember]
        public int Rooms { get; set; }
        [DataMember]
        public int Rent { get; set; }
        [DataMember]
        public string Picture { get; set; }
        [DataMember]
        public RealEstateType Type { get; set; } //this is just an enum
        public string Address { get; set; }
        [DataMember]
        public List<string> Images { get; set; }
        public string Name { get; set; }
        [DataMember]
        public string Email { get; set; }
        [DataMember]
        public string Phone { get; set; }
        [DataMember]
        public string Phone2 { get; set; }
        [DataMember]
        public string OriginalUrl { get; set; }
        [DataMember]
        public string OriginalSource { get; set; }
        [DataMember]
        public string City { get; set; }
        [DataMember]
        public int ZipCode { get; set; }
        [DataMember]
        public string StreetAddress { get; set; }
        [DataMember]
        public double Longtitude { get; set; }
        [DataMember]
        public double Latitude { get; set; }
}

More information about Data Contracts