微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

json – 执行ajax调用时序列化类型对象时检测到循环引用

在我看来,我使用的是viewmodel,我有一个只有一个文本框的表单,它接受日期(不是viewmodel的一部分)和3个表.认情况下,页面加载..表格填充基于今天日期的数据(您可以在下面的控制器代码中看到),但如果用户选择日期并单击搜索按钮,那么我希望更改表格数据没有基于他们选择的日期刷新页面.

@using (Html.BeginForm())
{
    <div class="form-group mb-3 mt-3" style="margin-right: -1.3%;">
        <div class="input-group col-md-3 offset-md-9">
            @Html.TextBox("detailsDate",null,new { id = "Details-Date",@class = "form-control datetimepicker" })
            <div class="input-group-append">
                <button id="Details-Date-Btn" type="submit" class="btn btn-outline-primary"><span class="fa fa-search"></span></button>
            </div>
        </div>
    </div>
}

我想要做的是如果用户选择和日期并点击搜索按钮..我希望页面不刷新,表格数据已根据日期更改.截至目前,我得到:

A circular reference was detected while serializing an object of type ‘System.Data.Entity.DynamicProxies.tbl_WeighAssc_8AA7AB5F9DAB261D5142F1D5F5BA6705A588A5AAD2D369FBD4B4BC1BBE0487D4’.

视图模型

public class PersonnelDetailsVm
{
    private static ConnectionString db = new ConnectionString();
    public PersonnelDetailsVm()
    {
        CurrentWeekDates = new List<DateTime>();
        WeighAssociations = new List<tbl_WeighAssc>();
        ArrestAssociations = new List<tbl_TEUArrestAssc>();
        inspectionAssociations = new List<tblTEUinspectionAssc>();
    }
    public string IBM { get; set; }

    [display(Name = "Name")]
    public string UserName { get; set; }

    public bool Active { get; set; }

    public List<DateTime> CurrentWeekDates { get; set; }
    public List<tbl_WeighAssc> WeighAssociations { get; set; }
    public List<tbl_TEUArrestAssc> ArrestAssociations { get; set; }
    public List<tblTEUinspectionAssc> inspectionAssociations { get; set; }
    public List<code_WeighLocation> WeighLocations => db.code_WeighLocation.ToList();
    public List<code_ArrestType> ArrestTypes => db.code_ArrestType.ToList();
    public List<code_inspectionLevel> inspectionLevels => db.code_inspectionLevel.ToList();
}

阿贾克斯:

// Submission
//var redirectUrl = '@Url.Action("Index","Personnels")';
var settings = {};
settings.baseUri = '@Request.ApplicationPath';
var infoGetUrl = "";
if (settings.baseUri === "/AppName") {
    infoGetUrl = settings.baseUri + "/Personnels/Details/";
} else {
    infoGetUrl = settings.baseUri + "Personnels/Details/";
}

$("#Details-Date-Btn").click(function() {
    $.ajax({
        url: infoGetUrl,method: "POST",data: $("form").serialize(),success: function(response) {
            console.log("success");
            $("body").html(response);
        },error: function(jqXHR,textStatus,errorThrown) {
            console.log(jqXHR);
        }
    });
});

控制器:

public ActionResult Details(string id,string detailsDate)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    tblPersonnel tblPersonnel = db.tblPersonnels.Find(id);

    if (tblPersonnel == null)
    {
        return HttpNotFound();
    }

    Mapper.Initialize(config => config.CreateMap<tblPersonnel,PersonnelDetailsVm>());
    PersonnelDetailsVm person = Mapper.Map<tblPersonnel,PersonnelDetailsVm>(tblPersonnel);

    var employeeData = EmployeeData.GetEmployee(person.IBM);

    person.UserName =
        $"{ConvertRankAbbr.Conversion(employeeData.Rank_Position)} {employeeData.FirstName} {employeeData.LastName}";

    if (string.IsNullOrWhiteSpace(detailsDate))
    {
        var startOfWeek = DateTime.Today.AddDays((int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek -
                                                 (int)DateTime.Today.DayOfWeek);
        person.CurrentWeekDates = Enumerable.Range(0,7).Select(i => startOfWeek.AddDays(i)).ToList();
        var teuFormIds = db.tbl_TEUForm
            .Where(x => person.CurrentWeekDates.Contains(x.EventDate) && x.Personnelibm == person.IBM).Select(t => t.Id).ToList();

        person.WeighAssociations = db.tbl_WeighAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
        person.ArrestAssociations = db.tbl_TEUArrestAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
        person.inspectionAssociations =
            db.tblTEUinspectionAsscs.Where(x => teuFormIds.Contains(x.TEUId)).ToList();


        return View(person);

    }
    else
    {
        var paramDate = DateTime.ParseExact(detailsDate,"MM/dd/yyyy",CultureInfo.CurrentCulture);

        var startOfWeek = paramDate.AddDays((int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek -
                                                 (int)paramDate.DayOfWeek);
        person.CurrentWeekDates = Enumerable.Range(0,7).Select(i => startOfWeek.AddDays(i)).ToList();
        var teuFormIds = db.tbl_TEUForm
            .Where(x => person.CurrentWeekDates.Contains(x.EventDate) && x.Personnelibm == person.IBM).Select(t => t.Id).ToList();

        person.WeighAssociations = db.tbl_WeighAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
        person.ArrestAssociations = db.tbl_TEUArrestAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
        person.inspectionAssociations =
            db.tblTEUinspectionAsscs.Where(x => teuFormIds.Contains(x.TEUId)).ToList();

        return Json(person,JsonRequestBehavior.AllowGet);
    }

}

因此,如果actionresult的参数detailsDate不为null,那么它将进入else语句,该语句返回一个JSON对象.经过调试后,当视图返回时,我收到上面发布的错误.

有没有办法用我从ajax调用返回内容替换视图中的模型,这样表可以基于正确的日期而不刷新页面

任何帮助是极大的赞赏.

UPDATE

基于下面的答案,我在我的控制器方法中编辑了else语句:

调节器

else
{
    var paramDate = DateTime.ParseExact(detailsDate,CultureInfo.CurrentCulture);

    var startOfWeek = paramDate.AddDays((int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek -
                                             (int)paramDate.DayOfWeek);
    person.CurrentWeekDates = Enumerable.Range(0,7).Select(i => startOfWeek.AddDays(i)).ToList();
    var teuFormIds = db.tbl_TEUForm
        .Where(x => person.CurrentWeekDates.Contains(x.EventDate) && x.Personnelibm == person.IBM).Select(t => t.Id).ToList();

    person.WeighAssociations = db.tbl_WeighAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
    person.ArrestAssociations = db.tbl_TEUArrestAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
    person.inspectionAssociations =
        db.tblTEUinspectionAsscs.Where(x => teuFormIds.Contains(x.TEUId)).ToList();

    JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
    {
        PreserveReferencesHandling = PreserveReferencesHandling.All,ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    };

    var jsonStr = JsonConvert.SerializeObject(person);

    return Json(jsonStr,"text/plain");
}

我的jQuery / Ajax仍然是一样的:

$("#Details-Date-Btn").click(function() {
    $.ajax({
        url: infoGetUrl,success: function(response) {
            console.log("success");
            console.log(response);
            $("body").html(response);
        },errorThrown) {
            console.log(jqXHR);
        }
    });
});

但现在,当选择日期时,我将返回到一个页面,该页面将Json显示为纯文本文件,并像普通视图一样丢失HTML和CSS.

这是我选择日期并单击按钮时返回的内容.

enter image description here

另外,当我在选择日期时检查控制台并单击该日期的按钮发送到控制器时,我看到了这样:

enter image description here

更新2

这是我的一张桌子..其他的是相同的设置:

<table class="table table-bordered">
    <thead>
        <tr>
            <th></th>
            @foreach (var date in Model.CurrentWeekDates)
            {
                <th class="text-center">@date.ToString("ddd") <br /> @date.ToShortDateString()</th>
            }
                <th class="text-center table-success">Total For Week</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var weighLocation in Model.WeighLocations)
        {
            <tr class="text-center">
                <td class="table-dark">@weighLocation.Weigh_Location</td>
                @foreach (var date in Model.CurrentWeekDates)
                {
                    if (Model.WeighAssociations.Any(x => x.tbl_TEUForm.EventDate == date && x.WeighLocationId == weighLocation.ID))
                    {
                        <td>@Model.WeighAssociations.Single(x => x.tbl_TEUForm.EventDate == date && x.WeighLocationId == weighLocation.ID).OccurenceCount</td>
                    }
                    else
                    {
                        <td>0</td>
                    }

                }
                <td class="table-success font-weight-bold">@Model.WeighAssociations.Where(x => x.WeighLocationId == weighLocation.ID).Sum(x => x.OccurenceCount)</td>
            </tr>
        }
    </tbody>
</table>

解决方法

据我所知,要修复它,您可以执行以下步骤:

1-查看

添加局部视图(_Detail.cshtml)

您需要像_Detail这样的部分视图,其中包含您的表格,如下所示:

@model PersonnelDetailsVm  

<table class="table table-bordered">
    <thead>
        <tr>
            <th></th>
            @foreach (var date in Model.CurrentWeekDates)
            {
                <th class="text-center">@date.ToString("ddd") <br /> @date.ToShortDateString()</th>
            }
                <th class="text-center table-success">Total For Week</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var weighLocation in Model.WeighLocations)
        {
            <tr class="text-center">
                <td class="table-dark">@weighLocation.Weigh_Location</td>
                @foreach (var date in Model.CurrentWeekDates)
                {
                    if (Model.WeighAssociations.Any(x => x.tbl_TEUForm.EventDate == date && x.WeighLocationId == weighLocation.ID))
                    {
                        <td>@Model.WeighAssociations.Single(x => x.tbl_TEUForm.EventDate == date && x.WeighLocationId == weighLocation.ID).OccurenceCount</td>
                    }
                    else
                    {
                        <td>0</td>
                    }

                }
                <td class="table-success font-weight-bold">@Model.WeighAssociations.Where(x => x.WeighLocationId == weighLocation.ID).Sum(x => x.OccurenceCount)</td>
            </tr>
        }
    </tbody>
</table>

2-控制器

返回局部视图

您应该在控制器中填充模型并将其传递给局部视图.

public ActionResult Details(string id,7).Select(i => startOfWeek.AddDays(i)).ToList();
        var teuFormIds = db.tbl_TEUForm
            .Where(x => person.CurrentWeekDates.Contains(x.EventDate) && x.Personnelibm == person.IBM).Select(t => t.Id).ToList();

        person.WeighAssociations = db.tbl_WeighAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
        person.ArrestAssociations = db.tbl_TEUArrestAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
        person.inspectionAssociations =
            db.tblTEUinspectionAsscs.Where(x => teuFormIds.Contains(x.TEUId)).ToList();


        // return View(person); 



    }
    else
    {
        var paramDate = DateTime.ParseExact(detailsDate,7).Select(i => startOfWeek.AddDays(i)).ToList();
        var teuFormIds = db.tbl_TEUForm
            .Where(x => person.CurrentWeekDates.Contains(x.EventDate) && x.Personnelibm == person.IBM).Select(t => t.Id).ToList();

        person.WeighAssociations = db.tbl_WeighAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
        person.ArrestAssociations = db.tbl_TEUArrestAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
        person.inspectionAssociations =
            db.tblTEUinspectionAsscs.Where(x => teuFormIds.Contains(x.TEUId)).ToList();

        // return Json(person,JsonRequestBehavior.AllowGet);
    }

    // return PartialView with the person model
    return PartialView("_Detail",person);

}

正如您在上面的代码中看到的,您应该在代码中注释两行:

// return View(person); 
// return Json(person,JsonRequestBehavior.AllowGet);

3- Ajax电话

获取部分视图并填写表单

您没有对ajax调用进行任何更改,您可以这样做:

$("#Details-Date-Btn").click(function() {
    $.ajax({
        url: infoGetUrl,errorThrown) {
            console.log(jqXHR);
        }
    });
});

这种方式的响应是一个来自局部视图的html,它包含了你设计的所有类.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐