Web API - 返回复杂对象列表时出错
本文关键字:列表 出错 对象 复杂 API 返回 Web | 更新日期: 2023-09-27 18:33:14
我创建了一个 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);
}
}
我的 VM 如下所示:
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; }
}
但是,每当我转到端点时,我都会收到以下错误:
类型"Boligside.ViewModels.RealEstateVm"无法序列化。 考虑使用 DataContractAttribute 属性对其进行标记,并且 标记要序列化的所有成员 属性。如果类型是集合,请考虑 使用 CollectionDataContractAttribute 标记它。查看Microsoft 其他受支持类型的 .NET Framework 文档。
可能是什么问题?我不明白为什么我必须用 [数据合同属性] 标记我的虚拟机?
顺便说一下,完整的错误消息在这里:
此 XML 文件似乎没有任何关联的样式信息 有了它。文档树如下所示。 一个错误 发生了。 "对象内容"1"类型 无法序列化内容类型的响应正文 '应用程序/XML;字符集=UTF-8'。 System.InvalidOperationException 错误有 发生。 类型 "Boligside.ViewModels.RealEstateVm"无法序列化。考虑 使用 DataContractAttribute 属性标记它,并标记所有 要使用 DataMemberAttribute 序列化的成员 属性。如果类型是集合,请考虑使用 CollectionDataContractAttribute.请参阅 .NET 框架Microsoft 其他受支持类型的文档。 System.Runtime.Serialization.InvalidDataContractException 在 System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String 消息,键入类型(在 System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id, 运行时类型句柄类型句柄, 类型类型( at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(Int32 id, 运行时类型句柄类型句柄, 类型类型( 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, XmlWriterDedelegateator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle( at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDedelegateator 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 type, Object value, Stream writeStream, HttpContent content( at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancelToken 取消令牌( --- 从上一个位置开始的堆栈跟踪结束 异常---抛出 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task 任务(在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task 任务(在 System.Web.Http.WebHost.HttpControllerHandler.d__1b。移动下一个((
DTO 类缺少无参数构造函数。请参阅此处:为什么XML可序列化类需要无参数构造函数(很抱歉唤醒这个问题,但我现在有同样的问题(
正如错误所说,它无法序列化并考虑添加数据协定属性。
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; }
}
有关数据协定的详细信息
从浏览器调用 API 不会将 Accept Header 设置为 application/json,因此 api 将使用 XmlFormatter,默认情况下使用 DataContractSerializer,即选择加入。
您可以像这样更改 XML 的默认行为
// XML Serializer Settings
var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
// use UseXmlSerializer because we use opu-out in our model classes
xml.UseXmlSerializer = true;