在序列化住宅建筑类型的对象时检测到循环引用

时间:2014-07-01 17:54:48

标签: c# javascript ajax visual-studio-2013

尝试进行AJAX调用时收到以下异常。我不知道这是什么。

这是控制器的代码:

public JsonResult getBldgInfo(string type, short stories, int size)
    {
        var info = from r in db.ResidentialBuildings
                   where r.type == type
                   && r.stories == stories
                   && r.size == size
                   select new { r };
        return Json(info, JsonRequestBehavior.AllowGet);
    }

这是AJAX电话:

 $("#ResidentialBuildingSize").change(function () {
    infoHead = "infoHead";
    invisible = "invisible";
    type = $("#ResidentialBuildingType").val();
    stories = $("#ResidentialBuildingStories").val();
    size = $("#ResidentialBuildingSize").val();
    console.log(type);
    console.log(stories);
    console.log(size);
    url = "/ResidentialBuilding/getBldgInfo?type=" + type + "&stories=" + stories + "&size=" + size;
    console.log(url);
    $.getJSON(url, function (data) {
        console.log(data);
        $.each(data, function (index, value) {
            $("#titles").empty();
            $("#values").empty();
            $("#titles").append('<h5 class="' + infoHead + '">' + value.r.type + " (" + value.r.stories + ")" + '</h5>');
            $("#titles").append('<p>' + "Stories" + '</p>');
            $("#titles").append('<p>' + "Age" + '</p>');
            $("#titles").append('<p>' + "Size" + '</p>');
            $("#titles").append('<p>' + "Orientation" + '</p>');
            $("#titles").append('<p>' + "Shape" + '</p>');
            $("#titles").append('<p>' + "Floor Height" + '</p>');
            $("#titles").append('<p>' + "Foundation" + '</p>');
            $("#titles").append('<p>' + "Window Percent" + '</p>');
            $("#titles").append('<p>' + "Heating" + '</p>');
            $("#titles").append('<p>' + "Cooling" + '</p>');
            $("#values").append('<h5 class="' + infoHead + ' ' + invisible + '">' + '&nbsp;' + '</h5>');
            $("#values").append('<p><strong>' + value.r.stories + '</strong></p>');
            $("#values").append('<p><strong>' + value.r.age + '</strong></p>');
            $("#values").append('<p><strong>' + value.r.size + '</strong></p>');
            $("#values").append('<p><strong>' + value.r.orientation + '</strong></p>');
            $("#values").append('<p><strong>' + value.r.shape + '</strong></p>');
            $("#values").append('<p><strong>' + value.r.floorht + '</strong></p>');
            $("#values").append('<p><strong>' + value.r.foundation + '</strong></p>');
            $("#values").append('<p><strong>' + value.r.windowpercent + '</strong></p>');
            $("#values").append('<p><strong>' + value.r.heating + '</strong></p>');
            $("#values").append('<p><strong>' + value.r.cooling + '</strong></p>');
        });
    });
});

$("#info").click(function () {
    $("#bldgInfo").slideToggle('2000', 'linear');
});

如果我做错了,请告诉我。当我使用本地数据库时,这个确切的代码有效。

更新

这是ResidentialBuilding模型的代码。

namespace BIRDS.Models



public partial class ResidentialBuilding
{
    public ResidentialBuilding()
    {
        this.ResidentialDatas = new HashSet<ResidentialData>();
    }

    public int Id { get; set; }
    public string type { get; set; }
    public short stories { get; set; }
    public int size { get; set; }
    public string age { get; set; }
    public string orientation { get; set; }
    public string shape { get; set; }
    public int floorht { get; set; }
    public string foundation { get; set; }
    public int windowpercent { get; set; }
    public string heating { get; set; }
    public string cooling { get; set; }

    public virtual ICollection<ResidentialData> ResidentialDatas { get; set; }
}

}

3 个答案:

答案 0 :(得分:0)

您的模型中可能有导航属性,因此序列化程序会跟踪它们并从链接模型中获取对模型的引用,如果没有循环引用检测机制,此过程将无限延续。

要解决您的问题,请仅选择您感兴趣的属性:

var info = from r in db.ResidentialBuildings
    where r.type == type
    && r.stories == stories
    && r.size == size
    select new { r.stories, r.age, r.size /* etc. */ };

答案 1 :(得分:0)

我敢说你的ResidentialData课程还有一个回复ResidentialBuilding课程的参考资料。将序列化为JSON时会发生什么,JavaScriptSerializer会看到对集合的引用并开始序列化集合。在ResidentialData类中,它将引用视为原始ResidentialBuilding类 - 并且它将继续进一步序列化并永远进行。您需要做的是让序列化程序忽略其中任何一个成员 - 这取决于您的需求。

您可以通过在项目中添加对System.Web.Extensions程序集的引用来完成此操作。从这里,您将添加对序列化类(using System.Web.Script.Serialization;)的引用。

最后,您可以使用ScriptIgnoreAttribute标志,以便它不再序列化集合,也不会抛出循环引用。新类应该如下所示:

using System.Web.Script.Serialization;

public partial class ResidentialBuilding
{
    public ResidentialBuilding()
    {
        this.ResidentialDatas = new HashSet<ResidentialData>();
    }

    public int Id { get; set; }
    public string type { get; set; }
    public short stories { get; set; }
    public int size { get; set; }
    public string age { get; set; }
    public string orientation { get; set; }
    public string shape { get; set; }
    public int floorht { get; set; }
    public string foundation { get; set; }
    public int windowpercent { get; set; }
    public string heating { get; set; }
    public string cooling { get; set; }

    [ScriptIgnoreAttribute]
    public virtual ICollection<ResidentialData> ResidentialDatas { get; set; }
}

答案 2 :(得分:0)

我猜你的:

public virtual ICollection<ResidentialData> ResidentialDatas { get; set; }

是和Entity Framework导航属性,还是一个ResidentialData类有一个返回到ResidentialBuilding的导航属性。

您可以使用DTO来解决这个问题,可能使用类似AutoMapper的库在类型之间进行映射,根据需要忽略或添加属性。