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

时间:2016-02-05 00:45:53

标签: c# serialization asp.net-web-api asp.net-web-api2

我创建了一个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; }
}

但是每当我去端点时,我都会收到以下错误:

  

输入&#39; Boligside.ViewModels.RealEstateVm&#39;无法序列化。   考虑使用DataContractAttribute属性标记它,并且   标记您想要序列化的所有成员   DataMemberAttribute属性。如果类型是集合,请考虑   使用CollectionDataContractAttribute标记它。见微软   其他受支持类型的.NET Framework文档。

可能是什么问题?我不知道为什么我要用[DataContractAttribute]标记我的VM?

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

  

此XML文件似乎没有任何关联的样式信息   用它。文档树如下所示。一个错误   已经发生了。 &#39; ObjectContent`1&#39;类型   无法序列化内容类型的响应正文   &#39;应用/ XML;字符集= UTF-8&#39 ;.   System.InvalidOperationException     错误有   发生了。类型   &#39; Boligside.ViewModels.RealEstateVm&#39;无法序列化。考虑   使用DataContractAttribute属性标记它,并标记所有   要使用DataMemberAttribute序列化的成员数   属性。如果类型是集合,请考虑使用   CollectionDataContractAttribute。请参阅Microsoft .NET Framework   其他支持类型的文档。      System.Runtime.Serialization.InvalidDataContractException     在   System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(字符串   消息,类型类型)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的   作家,对象图)   System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(类型   type,Object value,Stream writeStream,HttpContent content)at   System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(类型   type,Object value,Stream writeStream,HttpContent内容,   TransportContext transportContext,CancellationToken   cancellationToken)---从前一个位置到底的堆栈跟踪结束   抛出异常---在   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   System.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()     

3 个答案:

答案 0 :(得分:6)

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

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

的更多信息

答案 1 :(得分:5)

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

答案 2 :(得分:0)

从浏览器调用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 out model classes
xml.UseXmlSerializer = true;