ASP.. NET Web API序列化JSON错误:“自我引用循环”

本文关键字:自我 引用 循环 错误 Web NET API 序列化 JSON ASP | 更新日期: 2023-09-27 18:05:54

这是一个长期的斗争。我和ASP一起工作。. NET web API提供与数据库的干净和简单的HTTP/JSON交互。我有一个实体名称Reservation,如下所示:

    // Reservation
public class Reservation
{
    public int ID { get; set; } // ID (Primary key)
    public int EquipmentID { get; set; } // EquipmentID
    public string Username { get; set; } // Username
    public DateTime BeginDateTime { get; set; } // BeginDateTime
    public int? Duration { get; set; } // Duration
    public int? ReservationStateID { get; set; } // ReservationStateID
    public DateTime? CheckInDateTime { get; set; } // CheckInDateTime
    public string Note { get; set; } // Note
    // Foreign keys
    public virtual Equipment Equipment { get; set; } // FK_Reservation_EquipmentID
    public virtual ReservationState ReservationState { get; set; } //FK_Reservation_ReservationState
}

到目前为止一切顺利。我正在运行一个简单的python脚本来创建一个新的预订,并与http请求一起传递一个reservation JSON对象。在以前的生活中,我在没有数据验证的情况下运行预订添加代码,并在HttpActionResult中返回reservation对象。我看到返回的是一个漂亮的json对象:

{u' username ': u'name', u' reservationstateid ': 1, u' equipment ': None, u' equipmentd ': 2, u' begindatetime ': u'2014-05-31T14:00:00Z', u' note ': u ", u' checkindatetime ': None, u' duration ': 10800, u' reservationstate ': None, u' id ': 51}

我有点担心外键设备和ReservationState被包含在返回的对象中,这可能会导致更大的问题,但在适当的时候。现在我尝试通过收集我的预订引用的设备项来运行数据验证

Equipment equipmentItem = await db.Equipment.FindAsync(newRes.EquipmentID);

现在,当我尝试执行相同的操作时,在相同的python脚本上使用相同的数据,收到的结果是一个可怕的大错误:

" 'ObjectContent ' 1'类型未能序列化内容类型'application/json的响应体;charset=utf-8'.", u' stacktrace ': None, u' message ':出现错误。, u' innerexception ': {u' exceptionmessage ': u"检测到类型为…的属性'Equipment'的自引用循环

我99%肯定,在我的数据库中的外键不创建循环引用,但唉,我在这里。我想再次指出在"成功"json结果中包含外键。我敢打赌,如果我能摆脱这些,我就能摆脱自我参照的问题。谢谢你的帮助!

ASP.. NET Web API序列化JSON错误:“自我引用循环”

错误是由EF为外键对象创建代理引起的,默认序列化器(DataContractSerializer)在使用代理进行序列化时出错。解决方案是在Global.asax.cs文件中添加以下行:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; 

虽然@SKall的答案确实解决了问题,但它并没有在整个项目中解决问题,只是解决了我给IgnoreDataMember属性的属性。

用IgnoreDataMember属性标记引用,并让我们知道这是否有帮助。

[IgnoreDataMember]
public virtual Equipment Equipment { get; set; }
[IgnoreDataMember]
public virtual ReservationState ReservationState { get; set; }