Web API - 返回复杂对象列表时出错

Web API - error when returning list of complex objects

我创建了一个如下所示的 webAPI 控制器方法:

 [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);
     }
}

我的虚拟机如下所示:

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; }
}

然而,每当我到达端点时,我都会收到以下错误:

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.

可能是什么问题?我不明白为什么我必须用 [DataContractAttribute]?

标记我的 VM

顺便说一句,完整的错误信息在这里:

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()

如错误所说,无法序列化,考虑添加数据契约属性..

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; }
}

有关Data Contracts

的更多信息

您的 DTO class 缺少无参数构造函数。看这里:Why XML-Serializable class need a parameterless constructor (很抱歉打醒这个问题,但我现在也有同样的问题)

从浏览器调用 API 不会将 Accept Header 设置为 application/json,因此 api 将使用默认使用 DataContractSerializer 的 XmlFormatter,这是可选的。

您可以像这样更改 XML 的默认行为

// XML Serializer Settings
var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
// use UseXmlSerializer because we use opu-out in our model classes
xml.UseXmlSerializer = true;