如何通过Ajax get请求从控制器将复杂对象传递到视图?

4

我试图通过JQuery的$.getJSON方法将一个复杂的ViewModel对象传递到我的视图中。然而,尽管对于简单对象它可以正常工作,但是当我的ViewModel包含其他对象列表时,我的Ajax请求就会停止工作。

这是我获取数据的方式:

$.getJSON('/Company/GetCompanies', function(data) { 
    viewModel.model = ko.mapping.fromJS(data)
    ko.applyBindings(viewModel)
});

这是一个工作的视图模型。
public class CompanyIndex
{
    public IList<CompanyWithDetail> Companies { get; set; }

    public void FillCompanies()
    {
        UnitOfWork unitOfWork = new UnitOfWork();
        unitOfWork.CompanyRepository.SetProxy(false);
        var CompanyFromDB = unitOfWork.CompanyRepository.GetCompanyWithDetails();

        Companies = new List<CompanyWithDetail>();
        foreach (Company company in CompanyFromDB)
        {
            CompanyWithDetail newCompany = new CompanyWithDetail();
            newCompany.CompanyName = company.CompanyName;
            Companies.Add(newCompany);

        }
        unitOfWork.Dispose();
    }
}

这是CompanWithDetail类,
// For sake of demonstration it only contains name
public class CompanyWithDetail
{
    public string CompanyName { get; set; }
}

这个很好。然而,当我添加

时,出现了问题。
public IList<CompanyFaxNumber> FaxNumber { get; set; }

将此属性添加到CompanyWithDetail类中,并在CompanyIndex视图模型的FillCompanies()方法中填充它,当我添加复杂对象时,我的ajax get请求停止工作。
顺便说一下,这是我的控制器,在两种情况下都返回正确的数据,但是当我添加复杂对象时,jquery的$.getJSON无法接收到数据。
public ActionResult GetCompanies()
{
    var model = new CompanyIndex();
    model.FillCompanies();
    return Json(model ,JsonRequestBehavior.AllowGet);   
}

编辑1:

当我说getJSON没有接收到数据时,我的意思是该函数体未被执行。

$.getJSON('/Company/GetCompanies', function(data) { 
    alert('test')
});

例如,当没有复杂对象时,警报正常工作,但当我添加对象到视图模型中时,它停止工作。
编辑2 当我从浏览器调用“Company/GetCompanies”而不是ajax时,出现以下错误:

在序列化类型为'CompanyManagement.Models.CompanyEmail'的对象时检测到循环引用。


我需要做些特殊的事情来将控制器中的复杂对象传递到视图吗?有什么想法吗?

所以您想返回CompanyWithDetails和所有相关的CompanyFaxNumbers吗? CompanyFaxNumber是一个实体吗?它是否具有对Company或CompanyWithDetail的反向引用? - Ladislav Mrnka
是的,它确实具有对公司的外键引用。我更新了我的问题。感谢您的评论。 - emre nevayeshirazi
3个回答

4

我需要在控制器和视图之间传递复杂对象,需要做些特殊的事情吗?

是的,你应该使用视图模型。如果对象层次结构之间存在循环引用,你将无法将其JSON序列化并通过网络发送。你需要打破这些循环引用,才能使你的模型可以被JSON序列化并发送。


1
+1 给那个老旧的“使用视图模型”的建议,我相信这将是你的墓志铭...;-) - Tom Chantler
1
使用视图模型,并停止将你的领域模型传递到视图中。这句话可以解决99.99%的人在开发ASP.NET MVC应用程序时遇到的问题。如果所有开发者都能遵循这一建议,那么asp.net-mvc标签在Stack Overflow上就会变成空荡荡的地方:-) 不幸的是,所有这些EF和CodeFirst的东西为那些开发者提供了太多的诱惑,他们很快就会掉进陷阱中。 - Darin Dimitrov
我明白你的观点。我在视图中需要模型本身的大部分属性,所以我直接在我的视图模型中使用了这些模型。谢谢你的提醒,以后会避免这样做。 - emre nevayeshirazi

1

0

您可以使用dataType=json轻松进行ajax post调用

    $.ajax({
                type: 'POST',
                url: '@Url.Action("actionName", "controllerName")',
            data: JSON.stringify({ *Perameter If Any* }),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (result) {                  
                  if (result != null) {

                } else {


                }
            }
           });

而你的操作方法应该是一个Json结果

public JsonResult ActionName(perameter)
    {

            var modle= getobject();
            return Json(modle);
  }

在上述情况中,您将在ajax调用的成功方法中收到一个值,该值将是您发送的完全相同的对象...无需序列化或任何技巧...就像它看起来那样简单。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接