Циклическая ссылка была обнаружена при сериализации объекта типа Жилое здание

#c# #javascript #ajax #visual-studio-2013

#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
                   amp;amp; r.stories == stories
                   amp;amp; 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   "amp;stories="   stories   "amp;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   '">'   'amp;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');
});
  

Пожалуйста, дайте мне знать, если я делаю что-то не так. Этот точный код работал, когда я работал с локальной базой данных.

Обновить

Вот код для модели жилого здания.

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

}

Комментарии:

1. Можете ли вы показать нам определение ResidentialBuilding класса? Я полагаю, что у вас есть ссылка на другой объект, который ссылается на ResidentialBuilding, вызывая циклическую ссылку.

2. если точный код работал с локальной базой данных .. тогда, возможно, ответ прямо перед вами .. то есть Database connection and or Database table проверьте конфигурационные файлы и убедитесь, что у вас все правильно указано, а также правильно настроено.. есть ли у вас пример фрагмента настроек базы данных обоих файлов .config, также убедитесь, что ResidentialBuildings контекст базы данных существует в отношении таблицы, из которой предполагается чтение и / или ссылка..

3. Добавлен код для модели. Пожалуйста, дайте мне знать.

4. Вам также нужно передать ResidentialDatas коллекцию на страницу?

Ответ №1:

Вероятно, у вас есть свойства навигации в вашей модели, поэтому сериализатор следует за ними и получает ссылку на вашу модель из связанной модели, этот процесс продолжался бы бесконечно, если бы не было механизма обнаружения циклической ссылки.

Чтобы решить вашу проблему, выберите только те свойства, которые вас интересуют:

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

Ответ №2:

Рискну предположить, что у вашего 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; }
}
  

Ответ №3:

Я собираюсь предположить, что ваш:

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

Это свойство навигации Entity Framework, а класс ResidentialData имеет свойство навигации обратно к ResidentialBuilding.

Вы можете использовать DTO, чтобы обойти это, возможно, используя библиотеку, подобную AutoMapper, для сопоставления между типами, игнорируя или добавляя свойства по мере необходимости.